]> Git Repo - binutils.git/blob - bfd/elf32-hppa.c
* libbfd.c, bfd-in.h, hosts/alphaosf.h, hosts/sparc-ll.h, aoutf1.h,
[binutils.git] / bfd / elf32-hppa.c
1 /* BFD back-end for HP PA-RISC ELF files.
2    Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
3
4    Written by
5
6         Center for Software Science
7         Department of Computer Science
8         University of Utah
9
10 This file is part of BFD, the Binary File Descriptor library.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
25
26 #include "bfd.h"
27 #include "sysdep.h"
28 #include "libbfd.h"
29 #include "obstack.h"
30 #include "bfdlink.h"
31 #include "libelf.h"
32
33 /* ELF32/HPPA relocation support
34
35         This file contains ELF32/HPPA relocation support as specified
36         in the Stratus FTX/Golf Object File Format (SED-1762) dated
37         November 19, 1992.
38 */
39
40 #include "elf32-hppa.h"
41 #include "libhppa.h"
42 #include "aout/aout64.h"
43 #include "hppa_stubs.h"
44
45 /* ELF/PA relocation howto entries */
46
47 static bfd_reloc_status_type hppa_elf_reloc
48   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
49
50 static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
51 {
52 /*  'bitpos' and 'abs' are obsolete */
53 /* type                 rs sz bsz pcrel  bpos abs    ovrf  sf              name */
54 /* 9.3.4. Address relocation types */
55   {R_HPPA_NONE, 0, 3, 19, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NONE"},
56   {R_HPPA_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_32"},
57   {R_HPPA_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_11"},
58   {R_HPPA_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_14"},
59   {R_HPPA_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_17"},
60 {R_HPPA_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L21"},
61 {R_HPPA_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R11"},
62 {R_HPPA_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R14"},
63 {R_HPPA_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_R17"},
64   {R_HPPA_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LS21"},
65   {R_HPPA_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS11"},
66   {R_HPPA_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS14"},
67   {R_HPPA_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RS17"},
68   {R_HPPA_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LD21"},
69   {R_HPPA_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD11"},
70   {R_HPPA_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD14"},
71   {R_HPPA_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RD17"},
72   {R_HPPA_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LR21"},
73   {R_HPPA_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR14"},
74   {R_HPPA_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_RR17"},
75 /* 9.3.5. GOTOFF address relocation types               */
76   {R_HPPA_GOTOFF_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_11"},
77   {R_HPPA_GOTOFF_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_14"},
78   {R_HPPA_GOTOFF_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_L21"},
79   {R_HPPA_GOTOFF_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R11"},
80   {R_HPPA_GOTOFF_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_R14"},
81   {R_HPPA_GOTOFF_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LS21"},
82   {R_HPPA_GOTOFF_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS11"},
83   {R_HPPA_GOTOFF_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RS14"},
84   {R_HPPA_GOTOFF_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LD21"},
85   {R_HPPA_GOTOFF_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD11"},
86   {R_HPPA_GOTOFF_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RD14"},
87   {R_HPPA_GOTOFF_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_LR21"},
88   {R_HPPA_GOTOFF_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_GOTOFF_RR14"},
89 /* 9.3.6. Absolute call relocation types        */
90   {R_HPPA_ABS_CALL_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_11"},
91   {R_HPPA_ABS_CALL_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_14"},
92   {R_HPPA_ABS_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_17"},
93   {R_HPPA_ABS_CALL_L21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_L21"},
94   {R_HPPA_ABS_CALL_R11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R11"},
95   {R_HPPA_ABS_CALL_R14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R14"},
96   {R_HPPA_ABS_CALL_R17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_R17"},
97   {R_HPPA_ABS_CALL_LS21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LS21"},
98   {R_HPPA_ABS_CALL_RS11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS11"},
99   {R_HPPA_ABS_CALL_RS14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS14"},
100   {R_HPPA_ABS_CALL_RS17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RS17"},
101   {R_HPPA_ABS_CALL_LD21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LD21"},
102   {R_HPPA_ABS_CALL_RD11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD11"},
103   {R_HPPA_ABS_CALL_RD14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD14"},
104   {R_HPPA_ABS_CALL_RD17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RD17"},
105   {R_HPPA_ABS_CALL_LR21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_LR21"},
106   {R_HPPA_ABS_CALL_RR14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR14"},
107   {R_HPPA_ABS_CALL_RR17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ABS_CALL_RR17"},
108 /* 9.3.7. PC-relative call relocation types     */
109   {R_HPPA_PCREL_CALL_11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_11"},
110   {R_HPPA_PCREL_CALL_14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_14"},
111   {R_HPPA_PCREL_CALL_17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_17"},
112   {R_HPPA_PCREL_CALL_12, 0, 3, 12, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_12"},
113   {R_HPPA_PCREL_CALL_L21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_L21"},
114   {R_HPPA_PCREL_CALL_R11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R11"},
115   {R_HPPA_PCREL_CALL_R14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R14"},
116   {R_HPPA_PCREL_CALL_R17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_R17"},
117   {R_HPPA_PCREL_CALL_LS21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LS21"},
118   {R_HPPA_PCREL_CALL_RS11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS11"},
119   {R_HPPA_PCREL_CALL_RS14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS14"},
120   {R_HPPA_PCREL_CALL_RS17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RS17"},
121   {R_HPPA_PCREL_CALL_LD21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LD21"},
122   {R_HPPA_PCREL_CALL_RD11, 0, 3, 11, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD11"},
123   {R_HPPA_PCREL_CALL_RD14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD14"},
124   {R_HPPA_PCREL_CALL_RD17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RD17"},
125   {R_HPPA_PCREL_CALL_LR21, 0, 3, 21, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_LR21"},
126   {R_HPPA_PCREL_CALL_RR14, 0, 3, 14, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR14"},
127   {R_HPPA_PCREL_CALL_RR17, 0, 3, 17, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PCREL_CALL_RR17"},
128
129 /* 9.3.8. Plabel relocation types */
130   {R_HPPA_PLABEL_32, 0, 3, 32, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_32"},
131   {R_HPPA_PLABEL_11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_11"},
132   {R_HPPA_PLABEL_14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_14"},
133   {R_HPPA_PLABEL_L21, 0, 3, 21, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_L21"},
134   {R_HPPA_PLABEL_R11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R11"},
135   {R_HPPA_PLABEL_R14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_PLABEL_R14"},
136
137 /* 9.3.9. Data linkage table (DLT) relocation types     */
138   {R_HPPA_DLT_32, 0, 3, 32, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_32"},
139   {R_HPPA_DLT_11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_11"},
140   {R_HPPA_DLT_14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_14"},
141   {R_HPPA_DLT_L21, 0, 3, 21, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_L21"},
142   {R_HPPA_DLT_R11, 0, 3, 11, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R11"},
143   {R_HPPA_DLT_R14, 0, 3, 14, false, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_DLT_R14"},
144
145 /* 9.3.10. Relocations for unwinder tables      */
146   {R_HPPA_UNWIND_ENTRY, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRY"},
147   {R_HPPA_UNWIND_ENTRIES, 0, 3, 32, true, 0, complain_overflow_signed, hppa_elf_reloc, "R_HPPA_UNWIND_ENTRIES"},
148
149 /*  9.3.11. Relocation types for complex expressions    */
150   {R_HPPA_PUSH_CONST, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_CONST"},
151   {R_HPPA_PUSH_PC, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PC"},
152   {R_HPPA_PUSH_SYM, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_SYM"},
153   {R_HPPA_PUSH_GOTOFF, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_GOTOFF"},
154   {R_HPPA_PUSH_ABS_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_ABS_CALL"},
155   {R_HPPA_PUSH_PCREL_CALL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PCREL_CALL"},
156   {R_HPPA_PUSH_PLABEL, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_PUSH_PLABEL"},
157 {R_HPPA_MAX, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MAX"},
158 {R_HPPA_MIN, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MIN"},
159 {R_HPPA_ADD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ADD"},
160 {R_HPPA_SUB, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_SUB"},
161   {R_HPPA_MULT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MULT"},
162 {R_HPPA_DIV, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_DIV"},
163 {R_HPPA_MOD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_MOD"},
164 {R_HPPA_AND, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_AND"},
165   {R_HPPA_OR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_OR"},
166 {R_HPPA_XOR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_XOR"},
167 {R_HPPA_NOT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_NOT"},
168   {R_HPPA_LSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LSHIFT"},
169   {R_HPPA_ARITH_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_ARITH_RSHIFT"},
170   {R_HPPA_LOGIC_RSHIFT, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_LOGIC_RSHIFT"},
171 {R_HPPA_EXPR_F, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_L"},
172   {R_HPPA_EXPR_L, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_L"},
173   {R_HPPA_EXPR_R, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_R"},
174   {R_HPPA_EXPR_LS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LS"},
175   {R_HPPA_EXPR_RS, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RS"},
176   {R_HPPA_EXPR_LD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LD"},
177   {R_HPPA_EXPR_RD, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RD"},
178   {R_HPPA_EXPR_LR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_LR"},
179   {R_HPPA_EXPR_RR, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_RR"},
180
181   {R_HPPA_EXPR_32, 0, 3, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_32"},
182   {R_HPPA_EXPR_21, 0, 3, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_21"},
183   {R_HPPA_EXPR_11, 0, 3, 11, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_11"},
184   {R_HPPA_EXPR_14, 0, 3, 14, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_14"},
185   {R_HPPA_EXPR_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_17"},
186   {R_HPPA_EXPR_12, 0, 3, 12, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_EXPR_12"},
187   {R_HPPA_STUB_CALL_17, 0, 3, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_HPPA_STUB_CALL_17"},
188   {R_HPPA_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_dont, NULL, "R_HPPA_UNIMPLEMENTED"},
189 };
190
191 static symext_chainS *symext_rootP;
192 static symext_chainS *symext_lastP;
193 static boolean symext_chain_built;
194
195 static unsigned long
196 hppa_elf_rebuild_insn (abfd, insn, value, r_type, r_field, r_format)
197      bfd *abfd;
198      unsigned long insn;
199      unsigned long value;
200      unsigned short r_type;
201      unsigned short r_field;
202      unsigned short r_format;
203 {
204   unsigned long const_part;     /* part of the instruction that does not change */
205   unsigned long rebuilt_part;
206
207   switch (r_format)
208     {
209     case 11:
210       {
211         unsigned w1, w;
212
213         const_part = insn & 0xffffe002;
214         dis_assemble_12 (value, &w1, &w);
215         rebuilt_part = (w1 << 2) | w;
216         return const_part | rebuilt_part;
217       }
218
219     case 12:
220       {
221         unsigned w1, w;
222
223         const_part = insn & 0xffffe002;
224         dis_assemble_12 (value, &w1, &w);
225         rebuilt_part = (w1 << 2) | w;
226         return const_part | rebuilt_part;
227       }
228
229     case 14:
230       const_part = insn & 0xffffc000;
231       low_sign_unext (value, 14, &rebuilt_part);
232       return const_part | rebuilt_part;
233
234     case 17:
235       {
236         unsigned w1, w2, w;
237
238         const_part = insn & 0xffe0e002;
239         dis_assemble_17 (value, &w1, &w2, &w);
240         rebuilt_part = (w2 << 2) | (w1 << 16) | w;
241         return const_part | rebuilt_part;
242       }
243
244     case 21:
245       const_part = insn & 0xffe00000;
246       dis_assemble_21 (value, &rebuilt_part);
247       return const_part | rebuilt_part;
248
249     case 32:
250       const_part = 0;
251       return value;
252
253     default:
254       fprintf (stderr, "Relocation problem : ");
255       fprintf (stderr,
256                "Unrecognized reloc type %d (fmt=%d,fld=%d), in module %s\n",
257                r_type, r_format, r_field, abfd->filename);
258     }
259   return insn;
260 }
261
262 static unsigned long
263 hppa_elf_relocate_insn (abfd, input_sect,
264                         insn, address, symp, sym_value, r_addend,
265                         r_type, r_format, r_field, pcrel)
266      bfd *abfd;
267      asection *input_sect;
268      unsigned long insn;
269      unsigned long address;
270      asymbol *symp;
271      long sym_value;
272      long r_addend;
273      unsigned short r_type;
274      unsigned short r_format;
275      unsigned short r_field;
276      unsigned char pcrel;
277 {
278   unsigned char opcode = get_opcode (insn);
279   long constant_value;
280   unsigned arg_reloc;
281
282   switch (opcode)
283     {
284     case LDO:
285     case LDB:
286     case LDH:
287     case LDW:
288     case LDWM:
289     case STB:
290     case STH:
291     case STW:
292     case STWM:
293       constant_value = HPPA_R_CONSTANT (r_addend);
294       BFD_ASSERT (r_format == 14);
295
296       if (pcrel)
297         sym_value -= address;
298       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
299       return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
300
301     case COMICLR:
302     case SUBI:                  /* case SUBIO: */
303     case ADDIT:         /* case ADDITO: */
304     case ADDI:                  /* case ADDIO: */
305       BFD_ASSERT (r_format == 11);
306
307       constant_value = HPPA_R_CONSTANT(r_addend);
308       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
309       return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
310
311     case LDIL:
312     case ADDIL:
313       BFD_ASSERT (r_format == 21);
314
315       constant_value = HPPA_R_CONSTANT (r_addend);
316       sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
317       return hppa_elf_rebuild_insn (abfd, insn, sym_value, r_type, r_field, r_format);
318
319     case BL:
320     case BE:
321     case BLE:
322       arg_reloc = HPPA_R_ARG_RELOC (r_addend);
323
324       BFD_ASSERT (r_format == 17);
325
326       /* XXX computing constant_value is not needed??? */
327       constant_value = assemble_17 ((insn & 0x001f0000) >> 16,
328                                     (insn & 0x00001ffc) >> 2,
329                                     insn & 1);
330       /* @@ Assumes only 32 bits.  */
331       constant_value = (constant_value << 15) >> 15;
332       if (pcrel)
333         {
334           sym_value -=
335             address + input_sect->output_offset
336             + input_sect->output_section->vma;
337           sym_value = hppa_field_adjust (sym_value, -8, r_field);
338         }
339       else
340         sym_value = hppa_field_adjust (sym_value, constant_value, r_field);
341
342       return hppa_elf_rebuild_insn (abfd, insn, sym_value >> 2, r_type, r_field, r_format);
343
344     default:
345       if (opcode == 0)
346         {
347           BFD_ASSERT (r_format == 32);
348           constant_value = HPPA_R_CONSTANT (r_addend);
349
350           return hppa_field_adjust (sym_value, constant_value, r_field);
351         }
352       else
353         {
354           fprintf (stderr,
355                    "Unrecognized opcode 0x%02x (fmt=%x,field=%x)\n",
356                    opcode, r_format, r_field);
357           return insn;
358         }
359     }
360 }
361
362 static void
363 hppa_elf_relocate_unwind_table (abfd, input_sect,
364                                 data, address, symp, sym_value, r_addend,
365                                 r_type, r_format, r_field, pcrel)
366      bfd *abfd;
367      asection *input_sect;
368      PTR data;
369      unsigned long address;
370      asymbol *symp;
371      long sym_value;
372      long r_addend;
373      unsigned short r_type;
374      unsigned short r_format;
375      unsigned short r_field;
376      unsigned char pcrel;
377 {
378   bfd_byte *hit_data = address + (bfd_byte *) (data);
379   long start_offset;
380   long end_offset;
381   long relocated_value;
382   int i;
383
384   BFD_ASSERT (r_format == 32);
385   BFD_ASSERT (r_field == e_fsel);
386   switch (r_type)
387     {
388     case R_HPPA_UNWIND_ENTRY:
389       start_offset = bfd_get_32 (abfd, hit_data);
390       relocated_value = hppa_field_adjust (sym_value, start_offset, r_field);
391       bfd_put_32 (abfd, relocated_value, hit_data);
392
393       hit_data += sizeof (unsigned long);
394       end_offset = bfd_get_32 (abfd, hit_data);
395       relocated_value = hppa_field_adjust (sym_value, end_offset, r_field);
396       bfd_put_32 (abfd, relocated_value, hit_data);
397       break;
398
399     case R_HPPA_UNWIND_ENTRIES:
400       for (i = 0; i < r_addend; i++, hit_data += 3 * sizeof (unsigned long))
401         {
402           unsigned int adjustment;
403           start_offset = bfd_get_32 (abfd, hit_data);
404           /* Stuff the symbol value into the first word */
405           /* of the  unwind descriptor */
406           bfd_put_32 (abfd, sym_value, hit_data);
407           adjustment = sym_value - start_offset;
408
409           hit_data += sizeof (unsigned long);
410           end_offset = adjustment + bfd_get_32 (abfd, hit_data);
411           bfd_put_32 (abfd, end_offset, hit_data);
412
413           /* If this is not the last unwind entry, */
414           /* adjust the symbol value. */
415           if (i + 1 < r_addend)
416             {
417               start_offset = bfd_get_32 (abfd, hit_data + 3 * sizeof (unsigned long));
418               sym_value = start_offset + adjustment;
419             }
420         }
421       break;
422
423     default:
424       fprintf (stderr,
425                "Unrecognized relocation type 0x%02x (fmt=%x,field=%x)\n",
426                r_type, r_format, r_field);
427     }
428 }
429
430 /* Provided the symbol, returns the value reffed */
431 static long
432 get_symbol_value (symbol)
433      asymbol *symbol;
434 {
435   long relocation = 0;
436
437   if (symbol == (asymbol *) NULL)
438     relocation = 0;
439   else if (symbol->section == &bfd_com_section)
440     {
441       relocation = 0;
442     }
443   else
444     {
445       relocation = symbol->value +
446         symbol->section->output_section->vma +
447         symbol->section->output_offset;
448     }
449
450   return (relocation);
451 }
452
453 /* This function provides a pretty straight-forward mapping between a */
454 /* base relocation type, format and field into the relocation type */
455 /* that will be emitted in an object file.  The only wrinkle in the */
456 /* mapping is that when the T, TR, TL, P, PR, or PL expression */
457 /* prefixes are involved, the type gets promoted to a *_GOTOFF_* */
458 /* relocation (in the case of T, TR, and TL) or a PLABEL relocation */
459 /* (in the case of P, PR, and PL).      */
460
461 /* NOTE: XXX the T, TR, TL, P, PR, and PL expression prefixes are not */
462 /* handled yet. */
463
464 static void
465 hppa_elf_gen_reloc_error (base_type, fmt, field)
466      elf32_hppa_reloc_type base_type;
467      int fmt;
468      int field;
469 {
470   fprintf (stderr, "undefined relocation: base=0x%x,fmt=0x%x,field=0x%x\n",
471            base_type, fmt, field);
472 }
473
474 elf32_hppa_reloc_type **
475 hppa_elf_gen_reloc_type (abfd, base_type, format, field)
476      bfd *abfd;
477      elf32_hppa_reloc_type base_type;
478      int format;
479      int field;
480 {
481 #define UNDEFINED       hppa_elf_gen_reloc_error(base_type,format,field)
482
483   elf32_hppa_reloc_type *finaltype;
484   elf32_hppa_reloc_type **final_types;
485   int i;
486
487   final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 2);
488   BFD_ASSERT (final_types != 0);
489
490   finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type));
491   BFD_ASSERT (finaltype != 0);
492
493   final_types[0] = finaltype;
494   final_types[1] = NULL;
495
496 #define final_type finaltype[0]
497
498   final_type = base_type;
499
500   switch (base_type)
501     {
502     case R_HPPA:
503       switch (format)
504         {
505         case 11:
506           switch (field)
507             {
508             case e_fsel:
509               final_type = R_HPPA_11;
510               break;
511             case e_rsel:
512               final_type = R_HPPA_R11;
513               break;
514             case e_rssel:
515               final_type = R_HPPA_RS11;
516               break;
517             case e_rdsel:
518               final_type = R_HPPA_RD11;
519               break;
520
521             case e_psel:
522               final_type = R_HPPA_PLABEL_11;
523               break;
524             case e_rpsel:
525               final_type = R_HPPA_PLABEL_R11;
526               break;
527             case e_tsel:
528               final_type = R_HPPA_DLT_11;
529               break;
530             case e_rtsel:
531               final_type = R_HPPA_DLT_R11;
532               break;
533
534             case e_lpsel:
535             case e_ltsel:
536             case e_lsel:
537             case e_lrsel:
538             case e_lssel:
539             case e_rrsel:
540             default:
541               UNDEFINED;
542               final_type = base_type;
543               break;
544             }
545           break;
546         case 12:
547           UNDEFINED;
548           break;
549         case 14:
550           switch (field)
551             {
552             case e_rsel:
553               final_type = R_HPPA_R14;
554               break;
555             case e_rssel:
556               final_type = R_HPPA_RS14;
557               break;
558             case e_rdsel:
559               final_type = R_HPPA_RD14;
560               break;
561             case e_rrsel:
562               final_type = R_HPPA_RR14;
563               break;
564
565             case e_psel:
566               final_type = R_HPPA_PLABEL_14;
567               break;
568             case e_rpsel:
569               final_type = R_HPPA_PLABEL_R14;
570               break;
571             case e_tsel:
572               final_type = R_HPPA_DLT_14;
573               break;
574             case e_rtsel:
575               final_type = R_HPPA_DLT_R14;
576               break;
577
578             case e_lpsel:
579             case e_ltsel:
580
581             case e_fsel:
582             case e_lsel:
583             case e_lssel:
584             case e_ldsel:
585             case e_lrsel:
586             default:
587               UNDEFINED;
588               final_type = base_type;
589               break;
590             }
591           break;
592         case 17:
593           switch (field)
594             {
595             case e_fsel:
596               final_type = R_HPPA_17;
597               break;
598             case e_rsel:
599               final_type = R_HPPA_R17;
600               break;
601             case e_rssel:
602               final_type = R_HPPA_RS17;
603               break;
604             case e_rdsel:
605               final_type = R_HPPA_RD17;
606               break;
607             case e_rrsel:
608               final_type = R_HPPA_RR17;
609               break;
610             case e_lsel:
611             case e_lssel:
612             case e_ldsel:
613             case e_lrsel:
614             default:
615               UNDEFINED;
616               final_type = base_type;
617               break;
618             }
619           break;
620         case 21:
621           switch (field)
622             {
623             case e_lsel:
624               final_type = R_HPPA_L21;
625               break;
626             case e_lssel:
627               final_type = R_HPPA_LS21;
628               break;
629             case e_ldsel:
630               final_type = R_HPPA_LD21;
631               break;
632             case e_lrsel:
633               final_type = R_HPPA_LR21;
634               break;
635             case e_lpsel:
636               final_type = R_HPPA_PLABEL_L21;
637               break;
638             case e_ltsel:
639               final_type = R_HPPA_PLABEL_L21;
640               break;
641             case e_rsel:
642             case e_rssel:
643             case e_rdsel:
644             case e_rrsel:
645             case e_fsel:
646             default:
647               UNDEFINED;
648               final_type = base_type;
649               break;
650             }
651           break;
652         case 32:
653           switch (field)
654             {
655             case e_fsel:
656               final_type = R_HPPA_32;
657               break;
658             case e_psel:
659               final_type = R_HPPA_PLABEL_32;
660               break;
661             case e_tsel:
662               final_type = R_HPPA_DLT_32;
663               break;
664             default:
665               UNDEFINED;
666               final_type = base_type;
667               break;
668             }
669           break;
670         default:
671           UNDEFINED;
672           final_type = base_type;
673           break;
674         }
675       break;
676     case R_HPPA_GOTOFF:
677       switch (format)
678         {
679         case 11:
680           switch (field)
681             {
682             case e_rsel:
683               final_type = R_HPPA_GOTOFF_R11;
684               break;
685             case e_rssel:
686               final_type = R_HPPA_GOTOFF_RS11;
687               break;
688             case e_rdsel:
689               final_type = R_HPPA_GOTOFF_RD11;
690               break;
691             case e_fsel:
692               final_type = R_HPPA_GOTOFF_11;
693               break;
694             case e_lsel:
695             case e_lrsel:
696             case e_lssel:
697             case e_rrsel:
698             default:
699               UNDEFINED;
700               final_type = base_type;
701               break;
702             }
703           break;
704         case 12:
705           UNDEFINED;
706           final_type = base_type;
707           break;
708         case 14:
709           switch (field)
710             {
711             case e_rsel:
712               final_type = R_HPPA_GOTOFF_R14;
713               break;
714             case e_rssel:
715               final_type = R_HPPA_GOTOFF_RS14;
716               break;
717             case e_rdsel:
718               final_type = R_HPPA_GOTOFF_RD14;
719               break;
720             case e_rrsel:
721               final_type = R_HPPA_GOTOFF_RR14;
722               break;
723             case e_fsel:
724               final_type = R_HPPA_GOTOFF_14;
725               break;
726             case e_lsel:
727             case e_lssel:
728             case e_ldsel:
729             case e_lrsel:
730             default:
731               UNDEFINED;
732               final_type = base_type;
733               break;
734             }
735           break;
736         case 17:
737           UNDEFINED;
738           final_type = base_type;
739           break;
740         case 21:
741           switch (field)
742             {
743             case e_lsel:
744               final_type = R_HPPA_GOTOFF_L21;
745               break;
746             case e_lssel:
747               final_type = R_HPPA_GOTOFF_LS21;
748               break;
749             case e_ldsel:
750               final_type = R_HPPA_GOTOFF_LD21;
751               break;
752             case e_lrsel:
753               final_type = R_HPPA_GOTOFF_LR21;
754               break;
755             case e_rsel:
756             case e_rssel:
757             case e_rdsel:
758             case e_rrsel:
759             case e_fsel:
760             default:
761               UNDEFINED;
762               final_type = base_type;
763               break;
764             }
765           break;
766         case 32:
767           UNDEFINED;
768           final_type = base_type;
769           break;
770         default:
771           UNDEFINED;
772           final_type = base_type;
773           break;
774         }
775       break;
776     case R_HPPA_PCREL_CALL:
777       switch (format)
778         {
779         case 11:
780           switch (field)
781             {
782             case e_rsel:
783               final_type = R_HPPA_PCREL_CALL_R11;
784               break;
785             case e_rssel:
786               final_type = R_HPPA_PCREL_CALL_RS11;
787               break;
788             case e_rdsel:
789               final_type = R_HPPA_PCREL_CALL_RD11;
790               break;
791             case e_fsel:
792               final_type = R_HPPA_PCREL_CALL_11;
793               break;
794             case e_lsel:
795             case e_lrsel:
796             case e_lssel:
797             case e_rrsel:
798             default:
799               UNDEFINED;
800               final_type = base_type;
801               break;
802             }
803           break;
804         case 12:
805           UNDEFINED;
806           final_type = base_type;
807           break;
808         case 14:
809           switch (field)
810             {
811             case e_rsel:
812               final_type = R_HPPA_PCREL_CALL_R14;
813               break;
814             case e_rssel:
815               final_type = R_HPPA_PCREL_CALL_RS14;
816               break;
817             case e_rdsel:
818               final_type = R_HPPA_PCREL_CALL_RD14;
819               break;
820             case e_rrsel:
821               final_type = R_HPPA_PCREL_CALL_RR14;
822               break;
823             case e_fsel:
824               final_type = R_HPPA_PCREL_CALL_14;
825               break;
826             case e_lsel:
827             case e_lssel:
828             case e_ldsel:
829             case e_lrsel:
830             default:
831               UNDEFINED;
832               final_type = base_type;
833               break;
834             }
835           break;
836         case 17:
837           switch (field)
838             {
839             case e_rsel:
840               final_type = R_HPPA_PCREL_CALL_R17;
841               break;
842             case e_rssel:
843               final_type = R_HPPA_PCREL_CALL_RS17;
844               break;
845             case e_rdsel:
846               final_type = R_HPPA_PCREL_CALL_RD17;
847               break;
848             case e_rrsel:
849               final_type = R_HPPA_PCREL_CALL_RR17;
850               break;
851             case e_fsel:
852               final_type = R_HPPA_PCREL_CALL_17;
853               break;
854             case e_lsel:
855             case e_lssel:
856             case e_ldsel:
857             case e_lrsel:
858             default:
859               UNDEFINED;
860               final_type = base_type;
861               break;
862             }
863           break;
864         case 21:
865           switch (field)
866             {
867             case e_lsel:
868               final_type = R_HPPA_PCREL_CALL_L21;
869               break;
870             case e_lssel:
871               final_type = R_HPPA_PCREL_CALL_LS21;
872               break;
873             case e_ldsel:
874               final_type = R_HPPA_PCREL_CALL_LD21;
875               break;
876             case e_lrsel:
877               final_type = R_HPPA_PCREL_CALL_LR21;
878               break;
879             case e_rsel:
880             case e_rssel:
881             case e_rdsel:
882             case e_rrsel:
883             case e_fsel:
884             default:
885               UNDEFINED;
886               final_type = base_type;
887               break;
888             }
889           break;
890         case 32:
891           UNDEFINED;
892           final_type = base_type;
893           break;
894         default:
895           UNDEFINED;
896           final_type = base_type;
897           break;
898         }
899       break;
900     case R_HPPA_PLABEL:
901       switch (format)
902         {
903         case 11:
904           switch (field)
905             {
906             case e_fsel:
907               final_type = R_HPPA_PLABEL_11;
908               break;
909             case e_rsel:
910               final_type = R_HPPA_PLABEL_R11;
911               break;
912             default:
913               UNDEFINED;
914               final_type = base_type;
915               break;
916             }
917           break;
918         case 14:
919           switch (field)
920             {
921             case e_fsel:
922               final_type = R_HPPA_PLABEL_14;
923               break;
924             case e_rsel:
925               final_type = R_HPPA_PLABEL_R14;
926               break;
927             default:
928               UNDEFINED;
929               final_type = base_type;
930               break;
931             }
932           break;
933         case 21:
934           switch (field)
935             {
936             case e_lsel:
937               final_type = R_HPPA_PLABEL_L21;
938               break;
939             default:
940               UNDEFINED;
941               final_type = base_type;
942               break;
943             }
944           break;
945         case 32:
946           switch (field)
947             {
948             case e_fsel:
949               final_type = R_HPPA_PLABEL_32;
950               break;
951             default:
952               UNDEFINED;
953               final_type = base_type;
954               break;
955             }
956           break;
957         default:
958           UNDEFINED;
959           final_type = base_type;
960           break;
961         }
962     case R_HPPA_ABS_CALL:
963       switch (format)
964         {
965         case 11:
966           switch (field)
967             {
968             case e_rsel:
969               final_type = R_HPPA_ABS_CALL_R11;
970               break;
971             case e_rssel:
972               final_type = R_HPPA_ABS_CALL_RS11;
973               break;
974             case e_rdsel:
975               final_type = R_HPPA_ABS_CALL_RD11;
976               break;
977             case e_fsel:
978               final_type = R_HPPA_ABS_CALL_11;
979               break;
980             case e_lsel:
981             case e_lrsel:
982             case e_lssel:
983             case e_rrsel:
984             default:
985               UNDEFINED;
986               final_type = base_type;
987               break;
988             }
989           break;
990         case 12:
991           UNDEFINED;
992           final_type = base_type;
993           break;
994         case 14:
995           switch (field)
996             {
997             case e_rsel:
998               final_type = R_HPPA_ABS_CALL_R14;
999               break;
1000             case e_rssel:
1001               final_type = R_HPPA_ABS_CALL_RS14;
1002               break;
1003             case e_rdsel:
1004               final_type = R_HPPA_ABS_CALL_RD14;
1005               break;
1006             case e_rrsel:
1007               final_type = R_HPPA_ABS_CALL_RR14;
1008               break;
1009             case e_fsel:
1010               final_type = R_HPPA_ABS_CALL_14;
1011               break;
1012             case e_lsel:
1013             case e_lssel:
1014             case e_ldsel:
1015             case e_lrsel:
1016             default:
1017               UNDEFINED;
1018               final_type = base_type;
1019               break;
1020             }
1021           break;
1022         case 17:
1023           switch (field)
1024             {
1025             case e_rsel:
1026               final_type = R_HPPA_ABS_CALL_R17;
1027               break;
1028             case e_rssel:
1029               final_type = R_HPPA_ABS_CALL_RS17;
1030               break;
1031             case e_rdsel:
1032               final_type = R_HPPA_ABS_CALL_RD17;
1033               break;
1034             case e_rrsel:
1035               final_type = R_HPPA_ABS_CALL_RR17;
1036               break;
1037             case e_fsel:
1038               final_type = R_HPPA_ABS_CALL_17;
1039               break;
1040             case e_lsel:
1041             case e_lssel:
1042             case e_ldsel:
1043             case e_lrsel:
1044             default:
1045               UNDEFINED;
1046               final_type = base_type;
1047               break;
1048             }
1049           break;
1050         case 21:
1051           switch (field)
1052             {
1053             case e_lsel:
1054               final_type = R_HPPA_ABS_CALL_L21;
1055               break;
1056             case e_lssel:
1057               final_type = R_HPPA_ABS_CALL_LS21;
1058               break;
1059             case e_ldsel:
1060               final_type = R_HPPA_ABS_CALL_LD21;
1061               break;
1062             case e_lrsel:
1063               final_type = R_HPPA_ABS_CALL_LR21;
1064               break;
1065             case e_rsel:
1066             case e_rssel:
1067             case e_rdsel:
1068             case e_rrsel:
1069             case e_fsel:
1070             default:
1071               UNDEFINED;
1072               final_type = base_type;
1073               break;
1074             }
1075           break;
1076         case 32:
1077           UNDEFINED;
1078           final_type = base_type;
1079           break;
1080         default:
1081           UNDEFINED;
1082           final_type = base_type;
1083           break;
1084         }
1085       break;
1086     case R_HPPA_UNWIND:
1087       final_type = R_HPPA_UNWIND_ENTRY;
1088       break;
1089     case R_HPPA_COMPLEX:
1090     case R_HPPA_COMPLEX_PCREL_CALL:
1091     case R_HPPA_COMPLEX_ABS_CALL:
1092       final_types = (elf32_hppa_reloc_type **) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 6);
1093       BFD_ASSERT (final_types != 0);
1094
1095       finaltype = (elf32_hppa_reloc_type *) bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type) * 5);
1096       BFD_ASSERT (finaltype != 0);
1097
1098       for (i = 0; i < 5; i++)
1099         final_types[i] = &finaltype[i];
1100
1101       final_types[5] = NULL;
1102
1103       finaltype[0] = R_HPPA_PUSH_SYM;
1104
1105       if (base_type == R_HPPA_COMPLEX)
1106         finaltype[1] = R_HPPA_PUSH_SYM;
1107       else if (base_type == R_HPPA_COMPLEX_PCREL_CALL)
1108         finaltype[1] = R_HPPA_PUSH_PCREL_CALL;
1109       else                      /* base_type == R_HPPA_COMPLEX_ABS_CALL */
1110         finaltype[1] = R_HPPA_PUSH_ABS_CALL;
1111
1112       finaltype[2] = R_HPPA_SUB;
1113
1114       switch (field)
1115         {
1116         case e_fsel:
1117           finaltype[3] = R_HPPA_EXPR_F;
1118           break;
1119         case e_lsel:
1120           finaltype[3] = R_HPPA_EXPR_L;
1121           break;
1122         case e_rsel:
1123           finaltype[3] = R_HPPA_EXPR_R;
1124           break;
1125         case e_lssel:
1126           finaltype[3] = R_HPPA_EXPR_LS;
1127           break;
1128         case e_rssel:
1129           finaltype[3] = R_HPPA_EXPR_RS;
1130           break;
1131         case e_ldsel:
1132           finaltype[3] = R_HPPA_EXPR_LD;
1133           break;
1134         case e_rdsel:
1135           finaltype[3] = R_HPPA_EXPR_RD;
1136           break;
1137         case e_lrsel:
1138           finaltype[3] = R_HPPA_EXPR_LR;
1139           break;
1140         case e_rrsel:
1141           finaltype[3] = R_HPPA_EXPR_RR;
1142           break;
1143         }
1144
1145       switch (format)
1146         {
1147         case 11:
1148           finaltype[4] = R_HPPA_EXPR_11;
1149           break;
1150         case 12:
1151           finaltype[4] = R_HPPA_EXPR_12;
1152           break;
1153         case 14:
1154           finaltype[4] = R_HPPA_EXPR_14;
1155           break;
1156         case 17:
1157           finaltype[4] = R_HPPA_EXPR_17;
1158           break;
1159         case 21:
1160           finaltype[4] = R_HPPA_EXPR_21;
1161           break;
1162         case 32:
1163           finaltype[4] = R_HPPA_EXPR_32;
1164           break;
1165         }
1166
1167       break;
1168
1169     default:
1170       final_type = base_type;
1171       break;
1172     }
1173
1174   return final_types;
1175 }
1176
1177 #undef final_type
1178
1179
1180 /* this function is in charge of performing all the HP PA relocations */
1181 static long global_value;
1182 static long GOT_value;  /* XXX:  need to calculate this! For HPUX, GOT == DP */
1183 static asymbol *global_symbol;
1184 static int global_sym_defined;
1185
1186 static bfd_reloc_status_type
1187 hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
1188                 error_message)
1189      bfd *abfd;
1190      arelent *reloc_entry;
1191      asymbol *symbol_in;
1192      PTR data;
1193      asection *input_section;
1194      bfd *output_bfd;
1195      char **error_message;
1196 {
1197   unsigned long insn;
1198   long sym_value = 0;
1199   unsigned long addr = reloc_entry->address;
1200   bfd_byte *hit_data = addr + (bfd_byte *) (data);
1201   unsigned short r_type = reloc_entry->howto->type & 0xFF;
1202   unsigned short r_field = e_fsel;
1203   boolean r_pcrel = reloc_entry->howto->pc_relative;
1204   unsigned r_format = reloc_entry->howto->bitsize;
1205   long r_addend = reloc_entry->addend;
1206
1207   if (output_bfd)
1208     {
1209       /* Partial linking - do nothing */
1210       reloc_entry->address += input_section->output_offset;
1211       return bfd_reloc_ok;
1212     }
1213
1214   /* If performing final link and the symbol we're relocating against
1215      is undefined, then return an error.  */ 
1216   if (symbol_in && symbol_in->section == &bfd_und_section)
1217     return bfd_reloc_undefined;
1218
1219   sym_value = get_symbol_value (symbol_in);
1220
1221   /* Compute the value of $global$.  */
1222   if (!global_sym_defined)
1223     {
1224       if (global_symbol)
1225         {
1226           global_value = (global_symbol->value
1227                           + global_symbol->section->output_section->vma
1228                           + global_symbol->section->output_offset);
1229           GOT_value = global_value;
1230           global_sym_defined++;
1231         }
1232     }
1233
1234   /* Get the instruction word.  */
1235   insn = bfd_get_32 (abfd, hit_data);
1236
1237   /* Relocate the value based on one of the basic relocation types
1238
1239    basic_type_1:        relocation is relative to $global$
1240    basic_type_2:        relocation is relative to the current GOT
1241    basic_type_3:        relocation is an absolute call
1242    basic_type_4:        relocation is an PC-relative call
1243    basic_type_5:        relocation is plabel reference
1244    basic_type_6:        relocation is an unwind table relocation
1245    extended_type:       unimplemented  */
1246
1247   switch (r_type)
1248     {
1249     case R_HPPA_NONE:
1250       break;
1251
1252     /* Handle all the basic type 1 relocations.  */
1253     case R_HPPA_32:
1254       r_field = e_fsel;
1255       goto do_basic_type_1;
1256     case R_HPPA_11:
1257       r_field = e_fsel;
1258       goto do_basic_type_1;
1259     case R_HPPA_14:
1260       r_field = e_fsel;
1261       goto do_basic_type_1;
1262     case R_HPPA_17:
1263       r_field = e_fsel;
1264       goto do_basic_type_1;
1265     case R_HPPA_L21:
1266       r_field = e_lsel;
1267       goto do_basic_type_1;
1268     case R_HPPA_R11:
1269       r_field = e_rsel;
1270       goto do_basic_type_1;
1271     case R_HPPA_R14:
1272       r_field = e_rsel;
1273       goto do_basic_type_1;
1274     case R_HPPA_R17:
1275       r_field = e_rsel;
1276       goto do_basic_type_1;
1277     case R_HPPA_LS21:
1278       r_field = e_lssel;
1279       goto do_basic_type_1;
1280     case R_HPPA_RS11:
1281       r_field = e_rssel;
1282       goto do_basic_type_1;
1283     case R_HPPA_RS14:
1284       r_field = e_rssel;
1285       goto do_basic_type_1;
1286     case R_HPPA_RS17:
1287       r_field = e_ldsel;
1288       goto do_basic_type_1;
1289     case R_HPPA_LD21:
1290       r_field = e_ldsel;
1291       goto do_basic_type_1;
1292     case R_HPPA_RD11:
1293       r_field = e_rdsel;
1294       goto do_basic_type_1;
1295     case R_HPPA_RD14:
1296       r_field = e_rdsel;
1297       goto do_basic_type_1;
1298     case R_HPPA_RD17:
1299       r_field = e_rdsel;
1300       goto do_basic_type_1;
1301     case R_HPPA_LR21:
1302       r_field = e_lrsel;
1303       goto do_basic_type_1;
1304     case R_HPPA_RR14:
1305       r_field = e_rrsel;
1306       goto do_basic_type_1;
1307     case R_HPPA_RR17:
1308       r_field = e_rrsel;
1309
1310     do_basic_type_1:
1311       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1312                                      symbol_in, sym_value, r_addend,
1313                                      r_type, r_format, r_field, r_pcrel);
1314       break;
1315
1316     /* Handle all the basic type 2 relocations.  */
1317     case R_HPPA_GOTOFF_11:
1318       r_field = e_fsel;
1319       goto do_basic_type_2;
1320     case R_HPPA_GOTOFF_14:
1321       r_field = e_fsel;
1322       goto do_basic_type_2;
1323     case R_HPPA_GOTOFF_L21:
1324       r_field = e_lsel;
1325       goto do_basic_type_2;
1326     case R_HPPA_GOTOFF_R11:
1327       r_field = e_rsel;
1328       goto do_basic_type_2;
1329     case R_HPPA_GOTOFF_R14:
1330       r_field = e_rsel;
1331       goto do_basic_type_2;
1332     case R_HPPA_GOTOFF_LS21:
1333       r_field = e_lssel;
1334       goto do_basic_type_2;
1335     case R_HPPA_GOTOFF_RS11:
1336       r_field = e_rssel;
1337       goto do_basic_type_2;
1338     case R_HPPA_GOTOFF_RS14:
1339       r_field = e_rssel;
1340       goto do_basic_type_2;
1341     case R_HPPA_GOTOFF_LD21:
1342       r_field = e_ldsel;
1343       goto do_basic_type_2;
1344     case R_HPPA_GOTOFF_RD11:
1345       r_field = e_rdsel;
1346       goto do_basic_type_2;
1347     case R_HPPA_GOTOFF_RD14:
1348       r_field = e_rdsel;
1349       goto do_basic_type_2;
1350     case R_HPPA_GOTOFF_LR21:
1351       r_field = e_lrsel;
1352       goto do_basic_type_2;
1353     case R_HPPA_GOTOFF_RR14:
1354       r_field = e_rrsel;
1355
1356     do_basic_type_2:
1357       sym_value -= GOT_value;
1358       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1359                                      symbol_in, sym_value, r_addend,
1360                                      r_type, r_format, r_field, r_pcrel);
1361       break;
1362
1363     /* Handle all the basic type 3 relocations.  */
1364     case R_HPPA_ABS_CALL_11:
1365       r_field = e_fsel;
1366       goto do_basic_type_3;
1367     case R_HPPA_ABS_CALL_14:
1368       r_field = e_fsel;
1369       goto do_basic_type_3;
1370     case R_HPPA_ABS_CALL_17:
1371       r_field = e_fsel;
1372       goto do_basic_type_3;
1373     case R_HPPA_ABS_CALL_L21:
1374       r_field = e_lsel;
1375       goto do_basic_type_3;
1376     case R_HPPA_ABS_CALL_R11:
1377       r_field = e_rsel;
1378       goto do_basic_type_3;
1379     case R_HPPA_ABS_CALL_R14:
1380       r_field = e_rsel;
1381       goto do_basic_type_3;
1382     case R_HPPA_ABS_CALL_R17:
1383       r_field = e_rsel;
1384       goto do_basic_type_3;
1385     case R_HPPA_ABS_CALL_LS21:
1386       r_field = e_lssel;
1387       goto do_basic_type_3;
1388     case R_HPPA_ABS_CALL_RS11:
1389       r_field = e_lssel;
1390       goto do_basic_type_3;
1391     case R_HPPA_ABS_CALL_RS14:
1392       r_field = e_rssel;
1393       goto do_basic_type_3;
1394     case R_HPPA_ABS_CALL_RS17:
1395       r_field = e_rssel;
1396       goto do_basic_type_3;
1397     case R_HPPA_ABS_CALL_LD21:
1398       r_field = e_ldsel;
1399       goto do_basic_type_3;
1400     case R_HPPA_ABS_CALL_RD11:
1401       r_field = e_rdsel;
1402       goto do_basic_type_3;
1403     case R_HPPA_ABS_CALL_RD14:
1404       r_field = e_rdsel;
1405       goto do_basic_type_3;
1406     case R_HPPA_ABS_CALL_RD17:
1407       r_field = e_rdsel;
1408       goto do_basic_type_3;
1409     case R_HPPA_ABS_CALL_LR21:
1410       r_field = e_lrsel;
1411       goto do_basic_type_3;
1412     case R_HPPA_ABS_CALL_RR14:
1413       r_field = e_rrsel;
1414       goto do_basic_type_3;
1415     case R_HPPA_ABS_CALL_RR17:
1416       r_field = e_rrsel;
1417
1418     do_basic_type_3:
1419       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1420                                      symbol_in, sym_value, r_addend,
1421                                      r_type, r_format, r_field, r_pcrel);
1422       break;
1423
1424     /* Handle all the basic type 4 relocations.  */  
1425     case R_HPPA_PCREL_CALL_11:
1426       r_field = e_fsel;
1427       goto do_basic_type_4;
1428     case R_HPPA_PCREL_CALL_14:
1429       r_field = e_fsel;
1430       goto do_basic_type_4;
1431     case R_HPPA_PCREL_CALL_17:
1432       r_field = e_fsel;
1433       goto do_basic_type_4;
1434     case R_HPPA_PCREL_CALL_L21:
1435       r_field = e_lsel;
1436       goto do_basic_type_4;
1437     case R_HPPA_PCREL_CALL_R11:
1438       r_field = e_rsel;
1439       goto do_basic_type_4;
1440     case R_HPPA_PCREL_CALL_R14:
1441       r_field = e_rsel;
1442       goto do_basic_type_4;
1443     case R_HPPA_PCREL_CALL_R17:
1444       r_field = e_rsel;
1445       goto do_basic_type_4;
1446     case R_HPPA_PCREL_CALL_LS21:
1447       r_field = e_lssel;
1448       goto do_basic_type_4;
1449     case R_HPPA_PCREL_CALL_RS11:
1450       r_field = e_rssel;
1451       goto do_basic_type_4;
1452     case R_HPPA_PCREL_CALL_RS14:
1453       r_field = e_rssel;
1454       goto do_basic_type_4;
1455     case R_HPPA_PCREL_CALL_RS17:
1456       r_field = e_rssel;
1457       goto do_basic_type_4;
1458     case R_HPPA_PCREL_CALL_LD21:
1459       r_field = e_ldsel;
1460       goto do_basic_type_4;
1461     case R_HPPA_PCREL_CALL_RD11:
1462       r_field = e_rdsel;
1463       goto do_basic_type_4;
1464     case R_HPPA_PCREL_CALL_RD14:
1465       r_field = e_rdsel;
1466       goto do_basic_type_4;
1467     case R_HPPA_PCREL_CALL_RD17:
1468       r_field = e_rdsel;
1469       goto do_basic_type_4;
1470     case R_HPPA_PCREL_CALL_LR21:
1471       r_field = e_lrsel;
1472       goto do_basic_type_4;
1473     case R_HPPA_PCREL_CALL_RR14:
1474       r_field = e_rrsel;
1475       goto do_basic_type_4;
1476     case R_HPPA_PCREL_CALL_RR17:
1477       r_field = e_rrsel;
1478
1479     do_basic_type_4:
1480       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1481                                      symbol_in, sym_value, r_addend,
1482                                      r_type, r_format, r_field, r_pcrel);
1483       break;
1484
1485     /* Handle all the basic type 5 relocations.  */  
1486     case R_HPPA_PLABEL_32:
1487     case R_HPPA_PLABEL_11:
1488     case R_HPPA_PLABEL_14:
1489       r_field = e_fsel;
1490       goto do_basic_type_5;
1491     case R_HPPA_PLABEL_L21:
1492       r_field = e_lsel;
1493       goto do_basic_type_5;
1494     case R_HPPA_PLABEL_R11:
1495     case R_HPPA_PLABEL_R14:
1496       r_field = e_rsel;
1497     do_basic_type_5:
1498       insn = hppa_elf_relocate_insn (abfd, input_section, insn, addr,
1499                                      symbol_in, sym_value, r_addend,
1500                                      r_type, r_format, r_field, r_pcrel);
1501       break;
1502
1503     /* Handle all basic type 6 relocations.  */
1504     case R_HPPA_UNWIND_ENTRY:
1505     case R_HPPA_UNWIND_ENTRIES:
1506       hppa_elf_relocate_unwind_table (abfd, input_section, data, addr,
1507                                       symbol_in, sym_value, r_addend,
1508                                       r_type, r_format, r_field, r_pcrel);
1509       return bfd_reloc_ok;
1510
1511     /* Handle the stack operations and similar braindamage.  */
1512     case R_HPPA_PUSH_CONST:
1513     case R_HPPA_PUSH_PC:
1514     case R_HPPA_PUSH_SYM:
1515     case R_HPPA_PUSH_GOTOFF:
1516     case R_HPPA_PUSH_ABS_CALL:
1517     case R_HPPA_PUSH_PCREL_CALL:
1518     case R_HPPA_PUSH_PLABEL:
1519     case R_HPPA_MAX:
1520     case R_HPPA_MIN:
1521     case R_HPPA_ADD:
1522     case R_HPPA_SUB:
1523     case R_HPPA_MULT:
1524     case R_HPPA_DIV:
1525     case R_HPPA_MOD:
1526     case R_HPPA_AND:
1527     case R_HPPA_OR:
1528     case R_HPPA_XOR:
1529     case R_HPPA_NOT:
1530     case R_HPPA_LSHIFT:
1531     case R_HPPA_ARITH_RSHIFT:
1532     case R_HPPA_LOGIC_RSHIFT:
1533     case R_HPPA_EXPR_F:
1534     case R_HPPA_EXPR_L:
1535     case R_HPPA_EXPR_R:
1536     case R_HPPA_EXPR_LS:
1537     case R_HPPA_EXPR_RS:
1538     case R_HPPA_EXPR_LD:
1539     case R_HPPA_EXPR_RD:
1540     case R_HPPA_EXPR_LR:
1541     case R_HPPA_EXPR_RR:
1542     case R_HPPA_EXPR_32:
1543     case R_HPPA_EXPR_21:
1544     case R_HPPA_EXPR_11:
1545     case R_HPPA_EXPR_14:
1546     case R_HPPA_EXPR_17:
1547     case R_HPPA_EXPR_12:
1548       fprintf (stderr, "Relocation problem: ");
1549       fprintf (stderr, "Unimplemented reloc type %d, in module %s\n",
1550                r_type, abfd->filename);
1551       return bfd_reloc_notsupported;
1552
1553     /* This is a linker internal relocation.  */
1554     case R_HPPA_STUB_CALL_17:
1555       /* This relocation is for a branch to a long branch stub.
1556          Change instruction to a BLE,N.  It may also be necessary
1557          to change interchange the branch and its delay slot.
1558          The original instruction stream is
1559
1560             bl <foo>,r          ; call foo using register r as
1561                                 ; the return pointer
1562             XXX                 ; delay slot instruction
1563
1564          The new instruction stream will be:
1565
1566             XXX                 ; delay slot instruction
1567             ble <foo_stub>      ; call the long call stub for foo
1568                                 ; using r31 as the return pointer
1569
1570          This braindamage is necessary because the compiler may put
1571          an instruction which uses %r31 in the delay slot of the original
1572          call.  By changing the call instruction from a "bl" to a "ble"
1573          %r31 gets clobbered before the delay slot executes.
1574
1575          We do not interchange the branch and delay slot if the delay
1576          slot was already nullified, or if the instruction in the delay
1577          slot modifies the return pointer to avoid an unconditional
1578          jump after the call returns (GCC optimization).  */
1579          
1580       if (insn & 2)
1581         {
1582           insn = BLE_N_XXX_0_0;
1583           bfd_put_32 (abfd, insn, hit_data);
1584           r_type = R_HPPA_ABS_CALL_17;
1585           r_pcrel = 0;
1586           insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1587                                          addr, symbol_in, sym_value,
1588                                          r_addend, r_type, r_format,
1589                                          r_field, r_pcrel);
1590         }
1591       else
1592         {
1593           unsigned long old_delay_slot_insn = bfd_get_32 (abfd, hit_data + 4);
1594           unsigned rtn_reg = (insn & 0x03e00000) >> 21;
1595
1596           if (get_opcode (old_delay_slot_insn) == LDO)
1597             {
1598               unsigned ldo_src_reg = (old_delay_slot_insn & 0x03e00000) >> 21;
1599               unsigned ldo_target_reg = (old_delay_slot_insn & 0x001f0000) >> 16;
1600
1601               /* If the target of the LDO is the same as the return
1602                  register then there is no reordering.  We can leave the
1603                  instuction as a non-nullified BLE in this case.  */
1604               if (ldo_target_reg == rtn_reg)
1605                 {
1606                   unsigned long new_delay_slot_insn = old_delay_slot_insn;
1607
1608                   BFD_ASSERT(ldo_src_reg == ldo_target_reg);
1609                   new_delay_slot_insn &= 0xfc00ffff;
1610                   new_delay_slot_insn |= ((31 << 21) | (31 << 16));
1611                   bfd_put_32 (abfd, new_delay_slot_insn, hit_data + 4);
1612                   insn = BLE_XXX_0_0;
1613                   r_type = R_HPPA_ABS_CALL_17;
1614                   r_pcrel = 0;
1615                   insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1616                                                  addr, symbol_in, sym_value,
1617                                                  r_addend, r_type, r_format,
1618                                                  r_field, r_pcrel);
1619                   bfd_put_32 (abfd, insn, hit_data);
1620                   return bfd_reloc_ok;
1621                 }
1622               else if (rtn_reg == 31)
1623                 {
1624                   /* The return register is r31, so this is a millicode
1625                      call.  Do not perform any instruction reordering.  */
1626                   insn = BLE_XXX_0_0;
1627                   r_type = R_HPPA_ABS_CALL_17;
1628                   r_pcrel = 0;
1629                   insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1630                                                  addr, symbol_in, sym_value,
1631                                                  r_addend, r_type, r_format,
1632                                                  r_field, r_pcrel);
1633                   bfd_put_32 (abfd, insn, hit_data);
1634                   return bfd_reloc_ok;
1635                 }
1636               else
1637                 {
1638                   /* Check to see if the delay slot instruction has a
1639                      relocation.  If so, we need to change the address
1640                      field of it, because the instruction it relocates
1641                      is going to be moved.  */
1642                   arelent * next_reloc_entry = reloc_entry+1;
1643
1644                   if (next_reloc_entry->address == reloc_entry->address + 4)
1645                     next_reloc_entry->address -= 4;
1646
1647                   insn = old_delay_slot_insn;
1648                   bfd_put_32 (abfd, insn, hit_data);
1649                   insn = BLE_N_XXX_0_0;
1650                   bfd_put_32 (abfd, insn, hit_data + 4);
1651                   r_type = R_HPPA_ABS_CALL_17;
1652                   r_pcrel = 0;
1653                   insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1654                                                  addr + 4, symbol_in, 
1655                                                  sym_value, r_addend, r_type,
1656                                                  r_format, r_field, r_pcrel);
1657                   bfd_put_32 (abfd, insn, hit_data + 4);
1658                   return bfd_reloc_ok;
1659                 }
1660             }
1661           else if (rtn_reg == 31)
1662             {
1663               /* The return register is r31, so this is a millicode call.
1664                  Perform no instruction reordering in this case.  */
1665               insn = BLE_XXX_0_0;
1666               r_type = R_HPPA_ABS_CALL_17;
1667               r_pcrel = 0;
1668               insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1669                                              addr, symbol_in, sym_value,
1670                                              r_addend, r_type, r_format,
1671                                              r_field, r_pcrel);
1672               bfd_put_32 (abfd, insn, hit_data);
1673               return bfd_reloc_ok;
1674             }
1675           else
1676             {
1677               /* Check to see if the delay slot instruction has a
1678                  relocation.  If so, we need to change its address
1679                  field  because the instruction it relocates is going
1680                  to be moved.  */
1681               arelent * next_reloc_entry = reloc_entry+1;
1682
1683               if (next_reloc_entry->address == reloc_entry->address + 4)
1684                 next_reloc_entry->address -= 4;
1685
1686               insn = old_delay_slot_insn;
1687               bfd_put_32 (abfd, insn, hit_data);
1688               insn = BLE_N_XXX_0_0;
1689               bfd_put_32 (abfd, insn, hit_data + 4);
1690               r_type = R_HPPA_ABS_CALL_17;
1691               r_pcrel = 0;
1692               insn = hppa_elf_relocate_insn (abfd, input_section, insn,
1693                                              addr + 4, symbol_in, sym_value,
1694                                              r_addend, r_type, r_format,
1695                                              r_field, r_pcrel);
1696               bfd_put_32 (abfd, insn, hit_data + 4);
1697               return bfd_reloc_ok;
1698             }
1699         }
1700       break;
1701       
1702     default:
1703       *error_message = (char *) "Unrecognized reloc";
1704       return bfd_reloc_dangerous;
1705     }
1706
1707   /* Update the instruction word.  */
1708   bfd_put_32 (abfd, insn, hit_data);
1709   return (bfd_reloc_ok);
1710 }
1711
1712 static const reloc_howto_type *
1713 elf_hppa_reloc_type_lookup (arch, code)
1714      bfd_arch_info_type *arch;
1715      bfd_reloc_code_real_type code;
1716 {
1717   if ((int) code < (int) R_HPPA_UNIMPLEMENTED)
1718     {
1719       BFD_ASSERT ((int) elf_hppa_howto_table[(int) code].type == (int) code);
1720       return &elf_hppa_howto_table[(int) code];
1721     }
1722
1723   return (reloc_howto_type *) 0;
1724 }
1725
1726 #define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup
1727
1728
1729 void
1730 elf_hppa_tc_symbol (abfd, symbolP, sym_idx)
1731      bfd *abfd;
1732      elf_symbol_type *symbolP;
1733      int sym_idx;
1734 {
1735   symext_chainS *symextP;
1736   unsigned int arg_reloc;
1737
1738   /* Only functions can have argument relocations.  */
1739   if (!(symbolP->symbol.flags & BSF_FUNCTION))
1740     return;
1741
1742   arg_reloc = symbolP->tc_data.hppa_arg_reloc;
1743
1744   /* If there are no argument relocation bits, then no relocation is
1745      necessary.  Do not add this to the symextn section.  */
1746   if (arg_reloc == 0)
1747     return;
1748
1749   symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2);
1750
1751   symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx);
1752   symextP[0].next = &symextP[1];
1753
1754   symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc);
1755   symextP[1].next = NULL;
1756
1757   if (symext_rootP == NULL)
1758     {
1759       symext_rootP = &symextP[0];
1760       symext_lastP = &symextP[1];
1761     }
1762   else
1763     {
1764       symext_lastP->next = &symextP[0];
1765       symext_lastP = &symextP[1];
1766     }
1767 }
1768
1769 /* Accessor function for the list of symbol extension records. */
1770 symext_chainS *elf32_hppa_get_symextn_chain()
1771 {
1772   return symext_rootP;
1773 }
1774
1775 static symext_entryS *symextn_contents;
1776 static unsigned int symextn_contents_real_size;
1777
1778 void
1779 elf_hppa_tc_make_sections (abfd, ignored)
1780      bfd *abfd;
1781      PTR ignored;
1782 {
1783   symext_chainS *symextP;
1784   int size;
1785   int n;
1786   int i;
1787   void hppa_elf_stub_finish (); /* forward declaration */
1788   asection *symextn_sec;
1789
1790   hppa_elf_stub_finish (abfd);
1791
1792   if (symext_rootP == NULL)
1793     return;
1794
1795   for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
1796     ;
1797
1798   size = sizeof (symext_entryS) * n;
1799   symextn_sec = bfd_get_section_by_name (abfd, SYMEXTN_SECTION_NAME);
1800   if (symextn_sec == (asection *) 0)
1801     {
1802       symextn_sec = bfd_make_section (abfd, SYMEXTN_SECTION_NAME);
1803       bfd_set_section_flags (abfd,
1804                              symextn_sec,
1805          SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE | SEC_READONLY);
1806       symextn_sec->output_section = symextn_sec;
1807       symextn_sec->output_offset = 0;
1808       bfd_set_section_alignment (abfd, symextn_sec, 2);
1809     }
1810   symextn_contents = (symext_entryS *) bfd_alloc (abfd, size);
1811
1812   for (i = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++i)
1813     symextn_contents[i] = symextP->entry;
1814   symextn_contents_real_size = size;
1815   bfd_set_section_size (abfd, symextn_sec, symextn_contents_real_size);
1816
1817   return;
1818 }
1819
1820 /* Support for HP PA-RISC stub generation.
1821
1822    Written by
1823
1824         Center for Software Science
1825         Department of Computer Science
1826         University of Utah
1827
1828     */
1829
1830 /*
1831     HP-PA calling conventions state:
1832
1833     1. an argument relocation stub is required whenever the callee and
1834     caller argument relocation bits do not match exactly.  The exception
1835     to this rule is if either the caller or callee argument relocation
1836     bit are 00 (do not relocate).
1837
1838     2. The linker can optionally add a symbol record for the stub so that
1839     the stub can be reused.  The symbol record will be the same as the
1840     original export symbol record, except that the relocation bits will
1841     reflect the input of the stub, the type would be STUB and the symbol
1842     value will be the location of the relocation stub.
1843
1844     Other notes:
1845
1846     Stubs can be inserted *before* the section of the caller.  The stubs
1847     can be treated as calls to code that manipulates the arguments.
1848
1849  */
1850
1851 typedef enum
1852   {
1853     HPPA_STUB_ILLEGAL,
1854     HPPA_STUB_ARG_RELOC,
1855     HPPA_STUB_LONG_BRANCH
1856   } hppa_stub_type;
1857
1858 symext_entryS
1859 elf32_hppa_get_sym_extn (abfd, sym, type)
1860      bfd *abfd;
1861      asymbol *sym;
1862      int type;
1863 {
1864   /* This function finds the symbol extension record of the */
1865   /* specified type for the specified symbol.  It returns the */
1866   /* value of the symbol extension record.      */
1867   symext_entryS retval;
1868
1869   switch (type)
1870     {
1871     case HPPA_SXT_NULL:
1872       retval = (symext_entryS) 0;
1873       break;
1874     case HPPA_SXT_SYMNDX:
1875       retval = (symext_entryS) 0;       /* XXX: need to fix this */
1876       break;
1877     case HPPA_SXT_ARG_RELOC:
1878       {
1879         elf_symbol_type *esymP = (elf_symbol_type *) sym;
1880
1881         retval = (symext_entryS) esymP->tc_data.hppa_arg_reloc;
1882         break;
1883       }
1884     /* This should never happen.  */
1885     default:
1886       abort();
1887     }
1888   return retval;
1889 }
1890
1891 typedef struct elf32_hppa_stub_name_list_struct
1892 {
1893   /* name of this stub  */
1894   asymbol *sym;
1895   /* stub description for this stub  */
1896   struct elf32_hppa_stub_description_struct *stub_desc;
1897   /* pointer into stub contents  */
1898   int *stub_secp;
1899   /* size of this stub  */
1900   unsigned size;
1901   /* next stub name entry  */
1902   struct elf32_hppa_stub_name_list_struct *next;
1903 } elf32_hppa_stub_name_list;
1904
1905 typedef struct elf32_hppa_stub_description_struct
1906   {
1907     struct elf32_hppa_stub_description_struct *next;
1908     bfd *this_bfd;              /* bfd to which this stub applies */
1909     asection *stub_sec;         /* stub section for this bfd */
1910     unsigned relocs_allocated_cnt; /* count of relocations for this stub section */
1911     unsigned real_size;
1912     unsigned allocated_size;
1913     int *stub_secp;             /* pointer to the next available location in the buffer */
1914     char *stub_contents;        /* contents of the stubs for this bfd */
1915     elf32_hppa_stub_name_list *stub_listP;
1916     struct bfd_link_info *link_info;
1917   }
1918 elf32_hppa_stub_description;
1919
1920 static elf32_hppa_stub_description *elf_hppa_stub_rootP;
1921
1922 /* Locate the stub section information for the given bfd. */
1923 static elf32_hppa_stub_description *
1924 find_stubs (abfd, stub_sec)
1925      bfd *abfd;
1926      asection *stub_sec;
1927 {
1928   elf32_hppa_stub_description *stubP;
1929
1930   for (stubP = elf_hppa_stub_rootP; stubP; stubP = stubP->next)
1931     {
1932       if (stubP->this_bfd == abfd
1933           && stubP->stub_sec == stub_sec)
1934         return stubP;
1935     }
1936
1937   return (elf32_hppa_stub_description *) NULL;
1938 }
1939
1940 static elf32_hppa_stub_description *
1941 new_stub (abfd, stub_sec, link_info)
1942      bfd *abfd;
1943      asection *stub_sec;
1944      struct bfd_link_info *link_info;
1945 {
1946   elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
1947
1948   if (stub)
1949     return stub;
1950
1951   stub = (elf32_hppa_stub_description *) bfd_zalloc (abfd, sizeof (elf32_hppa_stub_description));
1952   if (stub)
1953     {
1954       stub->this_bfd = abfd;
1955       stub->stub_sec = stub_sec;
1956       stub->real_size = 0;
1957       stub->allocated_size = 0;
1958       stub->stub_contents = NULL;
1959       stub->stub_secp = NULL;
1960       stub->link_info = link_info;
1961
1962       stub->next = elf_hppa_stub_rootP;
1963       elf_hppa_stub_rootP = stub;
1964     }
1965   else
1966     {
1967       bfd_error = no_memory;
1968       bfd_perror ("new_stub");
1969     }
1970
1971   return stub;
1972 }
1973
1974 /* Locate the stub by the given name.  */
1975 static elf32_hppa_stub_name_list *
1976 find_stub_by_name (abfd, stub_sec, name)
1977      bfd *abfd;
1978      asection *stub_sec;
1979      char *name;
1980 {
1981   elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
1982
1983   if (stub)
1984     {
1985       elf32_hppa_stub_name_list *name_listP;
1986
1987       for (name_listP = stub->stub_listP; name_listP; name_listP = name_listP->next)
1988         {
1989           if (!strcmp (name_listP->sym->name, name))
1990             return name_listP;
1991         }
1992     }
1993
1994   return 0;
1995 }
1996
1997 /* Locate the stub by the given name.  */
1998 static elf32_hppa_stub_name_list *
1999 add_stub_by_name(abfd, stub_sec, sym, link_info)
2000      bfd *abfd;
2001      asection *stub_sec;
2002      asymbol *sym;
2003      struct bfd_link_info *link_info;
2004 {
2005   elf32_hppa_stub_description *stub = find_stubs (abfd, stub_sec);
2006   elf32_hppa_stub_name_list *stub_entry;
2007
2008   if (!stub)
2009     stub = new_stub(abfd, stub_sec, link_info);
2010
2011   if (stub)
2012     {
2013       stub_entry = (elf32_hppa_stub_name_list *)
2014         bfd_zalloc (abfd, sizeof (elf32_hppa_stub_name_list));
2015
2016       if (stub_entry)
2017         {
2018           stub_entry->size = 0;
2019           stub_entry->sym = sym;
2020           stub_entry->stub_desc = stub;
2021           /* First byte of this stub is the pointer to
2022              the next available location in the stub buffer.  */
2023           stub_entry->stub_secp = stub->stub_secp;
2024           if (stub->stub_listP)
2025             stub_entry->next = stub->stub_listP;
2026           else
2027             stub_entry->next = NULL;
2028           stub->stub_listP = stub_entry;
2029           return stub_entry;
2030         }
2031       else
2032         {
2033           bfd_error = no_memory;
2034           bfd_perror("add_stub_by_name");
2035         }
2036     }
2037
2038   return (elf32_hppa_stub_name_list *)NULL;
2039 }
2040
2041 #define ARGUMENTS       0
2042 #define RETURN_VALUE    1
2043
2044 #define NO_ARG_RELOC    0
2045 #define R_TO_FR         1
2046 #define R01_TO_FR       2
2047 #define R23_TO_FR       3
2048 #define FR_TO_R         4
2049 #define FR_TO_R01       5
2050 #define FR_TO_R23       6
2051 #define ARG_RELOC_ERR   7
2052
2053 #define ARG0    0
2054 #define ARG1    1
2055 #define ARG2    2
2056 #define ARG3    3
2057 #define RETVAL  4
2058
2059 #define AR_NO   0
2060 #define AR_GR   1
2061 #define AR_FR   2
2062 #define AR_FU   3
2063 /* FP register in arg0/arg1.  This value can only appear in the arg0 location. */
2064 #define AR_DBL01        4
2065 /* FP register in arg2/arg3.  This value can only appear in the arg2 location. */
2066 #define AR_DBL23        5
2067
2068 #define AR_WARN(type,loc) \
2069   fprintf(stderr,"WARNING:  Illegal argument relocation: %s for %s\n", \
2070           reloc_type_strings[type],reloc_loc_strings[loc])
2071
2072 static CONST char *CONST reloc_type_strings[] =
2073 {
2074   "NONE", "GR->FR", "GR0,GR1->FR1", "GR2,GR3->FR3", "FR->GR", "FR->GR0,GR1", "FR->GR2,GR3", "ERROR"
2075 };
2076
2077 static CONST char *CONST reloc_loc_strings[] =
2078 {
2079   "ARG0", "ARG1", "ARG2", "ARG3", "RETVAL"
2080 };
2081
2082 static CONST char mismatches[6][6] =
2083 {                               /*      CALLEE NONE     CALLEE GR       CALLEE FR       CALLEE FU       CALLEE DBL01    CALLEE DBL23    */
2084   /* CALLER NONE        */
2085  {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
2086  /* CALLER GR   */
2087  {NO_ARG_RELOC, NO_ARG_RELOC, R_TO_FR, ARG_RELOC_ERR, R01_TO_FR, ARG_RELOC_ERR},
2088  /* CALLER FR   */
2089  {NO_ARG_RELOC, FR_TO_R, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR},
2090  /* CALLER FU   */
2091  {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
2092  /* CALLER DBL01        */
2093  {NO_ARG_RELOC, FR_TO_R01, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
2094  /* CALLER DBL23        */
2095  {NO_ARG_RELOC, FR_TO_R23, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
2096 };
2097
2098 static CONST char retval_mismatches[6][6] =
2099 {       /*      CALLEE NONE     CALLEE GR       CALLEE FR       CALLEE FU       CALLEE DBL01    CALLEE DBL23    */
2100   /* CALLER NONE        */
2101  {NO_ARG_RELOC, NO_ARG_RELOC, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, NO_ARG_RELOC},
2102  /* CALLER GR   */
2103  {NO_ARG_RELOC, NO_ARG_RELOC, FR_TO_R, ARG_RELOC_ERR, FR_TO_R01, ARG_RELOC_ERR},
2104  /* CALLER FR   */
2105  {NO_ARG_RELOC, R_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
2106  /* CALLER FU   */
2107  {ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR, ARG_RELOC_ERR},
2108  /* CALLER DBL01        */
2109  {NO_ARG_RELOC, R01_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, NO_ARG_RELOC, ARG_RELOC_ERR},
2110  /* CALLER DBL23        */
2111  {NO_ARG_RELOC, R23_TO_FR, NO_ARG_RELOC, ARG_RELOC_ERR, ARG_RELOC_ERR, NO_ARG_RELOC},
2112 };
2113
2114 static int
2115 type_of_mismatch (caller_bits, callee_bits, type)
2116      int caller_bits;
2117      int callee_bits;
2118      int type;
2119 {
2120   switch (type)
2121     {
2122     case ARGUMENTS:
2123       return mismatches[caller_bits][callee_bits];
2124     case RETURN_VALUE:
2125       return retval_mismatches[caller_bits][callee_bits];
2126     }
2127
2128   return 0;
2129 }
2130
2131 #define EXTRACT_ARBITS(ar,which)        ((ar) >> (8-(which*2))) & 3
2132
2133 #define NEW_INSTRUCTION(entry,insn)     \
2134 { \
2135   *((entry)->stub_desc->stub_secp)++ = (insn);  \
2136   (entry)->stub_desc->real_size += sizeof(int); \
2137   (entry)->size += sizeof(int); \
2138   bfd_set_section_size((entry)->stub_desc->this_bfd,    \
2139                        (entry)->stub_desc->stub_sec,    \
2140                        (entry)->stub_desc->real_size);  \
2141 }
2142
2143 #define CURRENT_STUB_OFFSET(entry)      \
2144   ((int)(entry)->stub_desc->stub_secp \
2145    - (int)(entry)->stub_desc->stub_contents - 4)
2146
2147 static boolean stubs_finished = false;
2148
2149 void
2150 hppa_elf_stub_finish (output_bfd)
2151      bfd *output_bfd;
2152 {
2153   elf32_hppa_stub_description *stub_list = elf_hppa_stub_rootP;
2154   /* All the stubs have been built.  Finish up building */
2155   /* stub section.  Apply relocations to the section.   */
2156
2157   if ( stubs_finished )
2158     return;
2159
2160   for (; stub_list; stub_list = stub_list->next)
2161     {
2162       if (stub_list->real_size)
2163         {
2164           bfd *stub_bfd = stub_list->this_bfd;
2165           asection *stub_sec = bfd_get_section_by_name (stub_bfd, ".hppa_linker_stubs");
2166           bfd_size_type reloc_size;
2167           arelent **reloc_vector;
2168
2169           BFD_ASSERT (stub_sec == stub_list->stub_sec);
2170           reloc_size = bfd_get_reloc_upper_bound (stub_bfd, stub_sec);
2171           reloc_vector = (arelent **) alloca (reloc_size);
2172
2173           BFD_ASSERT (stub_sec);
2174
2175           /* We are not relaxing the section, so just copy the size info */
2176           stub_sec->_cooked_size = stub_sec->_raw_size;
2177           stub_sec->reloc_done = true;
2178
2179
2180           if (bfd_canonicalize_reloc (stub_bfd,
2181                                       stub_sec,
2182                                       reloc_vector,
2183                                       output_bfd->outsymbols))
2184             {
2185               arelent **parent;
2186               for (parent = reloc_vector; *parent != (arelent *) NULL;
2187                    parent++)
2188                 {
2189                   char *err = (char *) NULL;
2190                   bfd_reloc_status_type r =
2191                     bfd_perform_relocation (stub_bfd,
2192                                             *parent,
2193                                             stub_list->stub_contents,
2194                                             stub_sec, (bfd *) NULL, &err);
2195
2196
2197                   if (r != bfd_reloc_ok)
2198                     {
2199                       struct bfd_link_info *link_info = stub_list->link_info;
2200
2201                       switch (r)
2202                         {
2203                         case bfd_reloc_undefined:
2204                           if (! ((*link_info->callbacks->undefined_symbol)
2205                                  (link_info,
2206                                   bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
2207                                   stub_bfd, stub_sec, (*parent)->address)))
2208                             abort ();
2209                           break;
2210                         case bfd_reloc_dangerous:
2211                           if (! ((*link_info->callbacks->reloc_dangerous)
2212                                  (link_info, err, stub_bfd, stub_sec,
2213                                   (*parent)->address)))
2214                             abort ();
2215                           break;
2216                         case bfd_reloc_overflow:
2217                           {
2218                             if (! ((*link_info->callbacks->reloc_overflow)
2219                                    (link_info,
2220                                     bfd_asymbol_name (*(*parent)->sym_ptr_ptr),
2221                                     (*parent)->howto->name,
2222                                     (*parent)->addend,
2223                                     stub_bfd, stub_sec,
2224                                     (*parent)->address)))
2225                               abort ();
2226                           }
2227                           break;
2228                         case bfd_reloc_outofrange:
2229                         default:
2230                           abort ();
2231                           break;
2232                         }
2233                     }
2234                 }
2235             }
2236
2237           bfd_set_section_contents (output_bfd,
2238                                     stub_sec,
2239                                     stub_list->stub_contents,
2240                                     0,
2241                                     stub_list->real_size);
2242
2243           free (reloc_vector);
2244         }
2245     }
2246   stubs_finished = true;
2247 }
2248
2249 void
2250 hppa_elf_stub_branch_reloc (stub_desc,  /* the bfd */
2251                             output_bfd, /* the output bfd */
2252                             target_sym, /* the target symbol */
2253                             offset)     /* the offset within the stub buffer (pre-calculated) */
2254      elf32_hppa_stub_description *stub_desc;
2255      bfd *output_bfd;
2256      asymbol *target_sym;
2257      int offset;
2258 {
2259   /* Allocate a new relocation entry. */
2260   arelent relent;
2261   int size;
2262
2263   if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
2264     {
2265       if (stub_desc->stub_sec->relocation == NULL)
2266         {
2267           stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
2268           size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2269           stub_desc->stub_sec->relocation = (arelent *) bfd_zmalloc (size);
2270         }
2271       else
2272         {
2273           stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
2274           size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2275           stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
2276                                                                  size);
2277         }
2278     }
2279
2280   /* Fill in the details. */
2281   relent.address = offset;
2282   relent.addend = 0;
2283   relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2284   BFD_ASSERT (relent.sym_ptr_ptr);
2285
2286   relent.sym_ptr_ptr[0] = target_sym;
2287   relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, R_HPPA_PCREL_CALL_17);
2288
2289   /* Save it in the array of relocations for the stub section. */
2290
2291   memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
2292           &relent,
2293           sizeof (arelent));
2294 }
2295
2296 void
2297 hppa_elf_stub_reloc (stub_desc, /* the bfd */
2298                      output_bfd,        /* the output bfd */
2299                      target_sym,        /* the target symbol */
2300                      offset,    /* the offset within the stub buffer (pre-calculated) */
2301                      type)
2302      elf32_hppa_stub_description *stub_desc;
2303      bfd *output_bfd;
2304      asymbol *target_sym;
2305      int offset;
2306      elf32_hppa_reloc_type type;
2307 {
2308   /* Allocate a new relocation entry. */
2309   arelent relent;
2310   int size;
2311   Elf_Internal_Shdr *rela_hdr;
2312
2313   if (stub_desc->relocs_allocated_cnt == stub_desc->stub_sec->reloc_count)
2314     {
2315       if (stub_desc->stub_sec->relocation == NULL)
2316         {
2317           stub_desc->relocs_allocated_cnt = STUB_RELOC_INCR;
2318           size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2319           stub_desc->stub_sec->relocation = (arelent *) bfd_zmalloc (size);
2320         }
2321       else
2322         {
2323           stub_desc->relocs_allocated_cnt += STUB_RELOC_INCR;
2324           size = sizeof (arelent) * stub_desc->relocs_allocated_cnt;
2325           stub_desc->stub_sec->relocation = (arelent *) realloc (stub_desc->stub_sec->relocation,
2326                                                                  size);
2327         }
2328     }
2329
2330   rela_hdr = &elf_section_data(stub_desc->stub_sec)->rel_hdr;
2331   rela_hdr->sh_size += sizeof(Elf32_External_Rela);
2332
2333   /* Fill in the details. */
2334   relent.address = offset;
2335   relent.addend = 0;
2336   relent.sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd, sizeof (asymbol *));
2337   BFD_ASSERT (relent.sym_ptr_ptr);
2338
2339   relent.sym_ptr_ptr[0] = target_sym;
2340   relent.howto = bfd_reloc_type_lookup (stub_desc->this_bfd, type);
2341
2342   /* Save it in the array of relocations for the stub section. */
2343
2344   memcpy (&stub_desc->stub_sec->relocation[stub_desc->stub_sec->reloc_count++],
2345           &relent,
2346           sizeof (arelent));
2347 }
2348
2349 asymbol *
2350 hppa_elf_build_arg_reloc_stub (abfd, output_bfd, link_info, reloc_entry,
2351                                stub_types, rtn_adjust, data)
2352      bfd *abfd;
2353      bfd *output_bfd;
2354      struct bfd_link_info *link_info;
2355      arelent *reloc_entry;
2356      int stub_types[5];
2357      int rtn_adjust;
2358      unsigned *data;
2359 {
2360   asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
2361   elf32_hppa_stub_description *stub_desc = find_stubs (abfd, stub_sec);
2362   asymbol *stub_sym = NULL;
2363   asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
2364   asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
2365   int i;
2366   char stub_sym_name[128];
2367   elf32_hppa_stub_name_list *stub_entry;
2368   unsigned insn = data[0];
2369
2370   /* Perform some additional checks on whether we should really do the
2371      return adjustment.  For example, if the instruction is nullified
2372      or if the delay slot contains an instruction that modifies the return
2373      pointer, then the branch instructions should not be rearranged
2374      (rtn_adjust is false).  */
2375   if (insn & 2 || insn == 0)
2376     rtn_adjust = false;
2377   else
2378     {
2379       unsigned delay_insn = data[1];
2380
2381       if (get_opcode (delay_insn) == LDO
2382           && (((insn & 0x03e00000) >> 21) == ((delay_insn & 0x001f0000) >> 16)))
2383         rtn_adjust = false;
2384     }
2385
2386   /* See if the proper stub entry has already been made.  */
2387   if (!stub_sec)
2388     {
2389       BFD_ASSERT (stub_desc == NULL);
2390       stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
2391       bfd_set_section_flags (abfd,
2392                              stub_sec,
2393                              SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
2394                              | SEC_RELOC | SEC_CODE | SEC_READONLY);
2395       stub_sec->output_section = output_text_section->output_section;
2396       stub_sec->output_offset = 0;
2397       bfd_set_section_alignment (abfd, stub_sec, 2);
2398       stub_desc = new_stub (abfd, stub_sec, link_info);
2399     }
2400
2401   /* Make the stub if we did not find one already.  */
2402   if (!stub_desc)
2403     stub_desc = new_stub (abfd, stub_sec, link_info);
2404
2405   /* Allocate space to write the stub.
2406      FIXME.  Why using realloc?!?  */
2407   if (!stub_desc->stub_contents)
2408     {
2409       stub_desc->allocated_size = STUB_BUFFER_INCR;
2410       stub_desc->stub_contents = (char *) bfd_xmalloc (STUB_BUFFER_INCR);
2411     }
2412   else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
2413     {
2414       stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
2415       stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
2416                                                    stub_desc->allocated_size);
2417     }
2418
2419   stub_desc->stub_secp
2420     = (int *) (stub_desc->stub_contents + stub_desc->real_size);
2421
2422   sprintf (stub_sym_name,
2423            "_stub_%s_%02d_%02d_%02d_%02d_%02d_%s",
2424            reloc_entry->sym_ptr_ptr[0]->name,
2425            stub_types[0], stub_types[1], stub_types[2],
2426            stub_types[3], stub_types[4],
2427            rtn_adjust ? "RA" : "");
2428   stub_entry = find_stub_by_name (abfd, stub_sec, stub_sym_name);
2429
2430   if (stub_entry)
2431     {
2432       stub_sym = stub_entry->sym;
2433       /* Redirect the original relocation from the old symbol (a function)
2434          to the stub (the stub calls the function).  Should we need to
2435          change the relocation type?  */
2436       reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2437                                                           sizeof (asymbol *));
2438       reloc_entry->sym_ptr_ptr[0] = stub_sym;
2439       if (reloc_entry->howto->type != R_HPPA_PLABEL_32
2440           && (get_opcode(insn) == BLE
2441               || get_opcode (insn) == BE
2442               || get_opcode (insn) == BL))
2443         reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
2444     }
2445   else
2446     {
2447       /* Create a new symbol to point to this stub.  */
2448       stub_sym = bfd_make_empty_symbol (abfd);
2449       stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
2450       strcpy ((char *) stub_sym->name, stub_sym_name);
2451       stub_sym->value
2452         = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
2453       stub_sym->section = stub_sec;
2454       stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
2455       stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
2456
2457       /* Redirect the original relocation from the old symbol (a function)
2458          to the stub (the stub calls the function).  Change the type of
2459          relocation to be the internal use only stub R_HPPA_STUB_CALL_17.  */
2460       reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2461                                                           sizeof (asymbol *));
2462       reloc_entry->sym_ptr_ptr[0] = stub_sym;
2463       if (reloc_entry->howto->type != R_HPPA_PLABEL_32
2464           && (get_opcode (insn) == BLE
2465               || get_opcode (insn) == BE
2466               || get_opcode (insn) == BL))
2467         reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
2468
2469       /* Generate common code for all stubs.  */
2470
2471       NEW_INSTRUCTION (stub_entry, LDSID_31_1);
2472       NEW_INSTRUCTION (stub_entry, MTSP_1_SR0);
2473       NEW_INSTRUCTION (stub_entry, ADDI_8_SP);
2474
2475       /* Generate code to move the arguments around.  */
2476       for (i = ARG0; i < ARG3; i++)
2477         {
2478           if (stub_types[i] != NO_ARG_RELOC)
2479             {
2480               switch (stub_types[i])
2481                 {
2482                 case R_TO_FR:
2483                   switch (i)
2484                     {
2485                     case ARG0:
2486                       NEW_INSTRUCTION (stub_entry, STWS_ARG0_M8SP);
2487                       NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG0);
2488                       break;
2489                     case ARG1:
2490                       NEW_INSTRUCTION (stub_entry, STWS_ARG1_M8SP);
2491                       NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG1);
2492                       break;
2493                     case ARG2:
2494                       NEW_INSTRUCTION (stub_entry, STWS_ARG2_M8SP);
2495                       NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG2);
2496                       break;
2497                     case ARG3:
2498                       NEW_INSTRUCTION (stub_entry, STWS_ARG3_M8SP);
2499                       NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FARG3);
2500                       break;
2501                     }
2502                   continue;
2503                   
2504                 case R01_TO_FR:
2505                   switch (i)
2506                     {
2507                     case ARG0:
2508                       NEW_INSTRUCTION (stub_entry, STWS_ARG0_M4SP);
2509                       NEW_INSTRUCTION (stub_entry, STWS_ARG1_M8SP);
2510                       NEW_INSTRUCTION (stub_entry, FLDDS_M8SP_FARG1);
2511                       break;
2512                     default:
2513                       AR_WARN (stub_types[i],i);
2514                       break;
2515                     }
2516                   continue;
2517                   
2518                 case R23_TO_FR:
2519                   switch (i)
2520                     {
2521                     case ARG2:
2522                       NEW_INSTRUCTION (stub_entry, STWS_ARG2_M4SP);
2523                       NEW_INSTRUCTION (stub_entry, STWS_ARG3_M8SP);
2524                       NEW_INSTRUCTION (stub_entry, FLDDS_M8SP_FARG3);
2525                       break;
2526                     default:
2527                       AR_WARN (stub_types[i],i);
2528                       break;
2529                     }
2530                   continue;
2531                   
2532                 case FR_TO_R:
2533                   switch (i)
2534                     {
2535                     case ARG0:
2536                       NEW_INSTRUCTION (stub_entry, FSTWS_FARG0_M8SP);
2537                       NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG0);
2538                       break;
2539                     case ARG1:
2540                       NEW_INSTRUCTION (stub_entry, FSTWS_FARG1_M8SP);
2541                       NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG1);
2542                       break;
2543                     case ARG2:
2544                       NEW_INSTRUCTION (stub_entry, FSTWS_FARG2_M8SP);
2545                       NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG2);
2546                       break;
2547                     case ARG3:
2548                       NEW_INSTRUCTION (stub_entry, FSTWS_FARG3_M8SP);
2549                       NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG3);
2550                       break;
2551                     }
2552                   continue;
2553                   
2554                 case FR_TO_R01:
2555                   switch (i)
2556                     {
2557                     case ARG0:
2558                       NEW_INSTRUCTION (stub_entry, FSTDS_FARG1_M8SP);
2559                       NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG0);
2560                       NEW_INSTRUCTION (stub_entry, LDWS_M8SP_ARG1);
2561                       break;
2562                     default:
2563                       AR_WARN (stub_types[i],i);
2564                       break;
2565                     }
2566                   continue;
2567                   
2568                 case FR_TO_R23:
2569                   switch (i)
2570                     {
2571                     case ARG2:
2572                       NEW_INSTRUCTION (stub_entry, FSTDS_FARG3_M8SP);
2573                       NEW_INSTRUCTION (stub_entry, LDWS_M4SP_ARG2);
2574                       NEW_INSTRUCTION (stub_entry, LDWS_M8SP_ARG3);
2575                       break;
2576                     default:
2577                       AR_WARN (stub_types[i],i);
2578                       break;
2579                     }
2580                   continue;
2581                   
2582                 }
2583             }
2584         }
2585
2586       NEW_INSTRUCTION (stub_entry, ADDI_M8_SP_SP);
2587
2588       /* Adjust the return address if necessary.  */
2589       if (rtn_adjust)
2590         {
2591           NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
2592         }
2593       else
2594         NEW_INSTRUCTION (stub_entry, COPY_31_2);
2595
2596       /* Save the return address.  */
2597       NEW_INSTRUCTION (stub_entry, STW_RP_M8SP);
2598
2599       /* Long branch to the target function.  */
2600       NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
2601       hppa_elf_stub_reloc (stub_entry->stub_desc,
2602                            abfd,
2603                            target_sym,
2604                            CURRENT_STUB_OFFSET (stub_entry),
2605                            R_HPPA_L21);
2606       NEW_INSTRUCTION (stub_entry, BLE_XXX_0_31);
2607       hppa_elf_stub_reloc (stub_entry->stub_desc,
2608                            abfd,
2609                            target_sym,
2610                            CURRENT_STUB_OFFSET (stub_entry),
2611                            R_HPPA_ABS_CALL_R17);
2612       NEW_INSTRUCTION (stub_entry, COPY_31_2);
2613       
2614
2615       /* Restore the return address.  */
2616       NEW_INSTRUCTION (stub_entry, LDW_M8SP_RP);
2617       
2618       /* Generate the code to move the return value around.  */
2619       i = RETVAL;
2620       if (stub_types[i] != NO_ARG_RELOC)
2621         {
2622           switch (stub_types[i])
2623             {
2624             case R_TO_FR:
2625               NEW_INSTRUCTION (stub_entry, STWS_RET0_M8SP);
2626               NEW_INSTRUCTION (stub_entry, FLDWS_M8SP_FRET0);
2627               break;
2628               
2629             case FR_TO_R:
2630               NEW_INSTRUCTION (stub_entry, FSTWS_FRET0_M8SP);
2631               NEW_INSTRUCTION (stub_entry, LDWS_M4SP_RET0);
2632               break;
2633             }
2634         }
2635       NEW_INSTRUCTION (stub_entry, BV_N_0_RP);
2636     }
2637
2638   return stub_sym;
2639 }
2640
2641 int
2642 hppa_elf_arg_reloc_needed_p (abfd, reloc_entry, stub_types, caller_ar)
2643      bfd *abfd;
2644      arelent *reloc_entry;
2645      int stub_types[5];
2646      symext_entryS caller_ar;
2647 {
2648   /* If the symbol is still undefined, there is */
2649   /* no way to know if a stub is required.      */
2650
2651   if (reloc_entry->sym_ptr_ptr[0] && reloc_entry->sym_ptr_ptr[0]->section != &bfd_und_section)
2652     {
2653       symext_entryS callee_ar = elf32_hppa_get_sym_extn (abfd,
2654                                                 reloc_entry->sym_ptr_ptr[0],
2655                                                          HPPA_SXT_ARG_RELOC);
2656
2657       /* Now, determine if a stub is */
2658       /* required.  A stub is required if they the callee and caller    */
2659       /* argument relocation bits are both nonzero and not equal.       */
2660
2661       if (caller_ar && callee_ar)
2662         {
2663           /* Both are non-zero, we need to do further checking. */
2664           /* First, check if there is a return value relocation to be done */
2665           int caller_loc[5];
2666           int callee_loc[5];
2667
2668           callee_loc[RETVAL] = EXTRACT_ARBITS (callee_ar, RETVAL);
2669           caller_loc[RETVAL] = EXTRACT_ARBITS (caller_ar, RETVAL);
2670           callee_loc[ARG0] = EXTRACT_ARBITS (callee_ar, ARG0);
2671           caller_loc[ARG0] = EXTRACT_ARBITS (caller_ar, ARG0);
2672           callee_loc[ARG1] = EXTRACT_ARBITS (callee_ar, ARG1);
2673           caller_loc[ARG1] = EXTRACT_ARBITS (caller_ar, ARG1);
2674           callee_loc[ARG2] = EXTRACT_ARBITS (callee_ar, ARG2);
2675           caller_loc[ARG2] = EXTRACT_ARBITS (caller_ar, ARG2);
2676           callee_loc[ARG3] = EXTRACT_ARBITS (callee_ar, ARG3);
2677           caller_loc[ARG3] = EXTRACT_ARBITS (caller_ar, ARG3);
2678
2679           /* Check some special combinations.  For */
2680           /* example, if FU appears in ARG1 or ARG3, we */
2681           /* can move it to ARG0 or ARG2, respectively. */
2682
2683           if (caller_loc[ARG0] == AR_FU || caller_loc[ARG1] == AR_FU)
2684             {
2685               caller_loc[ARG0] = AR_DBL01;
2686               caller_loc[ARG1] = AR_NO;
2687             }
2688           if (caller_loc[ARG2] == AR_FU || caller_loc[ARG3] == AR_FU)
2689             {
2690               caller_loc[ARG2] = AR_DBL23;
2691               caller_loc[ARG3] = AR_NO;
2692             }
2693           if (callee_loc[ARG0] == AR_FU || callee_loc[ARG1] == AR_FU)
2694             {
2695               callee_loc[ARG0] = AR_DBL01;
2696               callee_loc[ARG1] = AR_NO;
2697             }
2698           if (callee_loc[ARG2] == AR_FU || callee_loc[ARG3] == AR_FU)
2699             {
2700               callee_loc[ARG2] = AR_DBL23;
2701               callee_loc[ARG3] = AR_NO;
2702             }
2703
2704           stub_types[ARG0] = type_of_mismatch (caller_loc[ARG0], callee_loc[ARG0], ARGUMENTS);
2705           stub_types[ARG1] = type_of_mismatch (caller_loc[ARG1], callee_loc[ARG1], ARGUMENTS);
2706           stub_types[ARG2] = type_of_mismatch (caller_loc[ARG2], callee_loc[ARG2], ARGUMENTS);
2707           stub_types[ARG3] = type_of_mismatch (caller_loc[ARG3], callee_loc[ARG3], ARGUMENTS);
2708           stub_types[RETVAL] = type_of_mismatch (caller_loc[RETVAL], callee_loc[RETVAL], RETURN_VALUE);
2709
2710           /* Steps involved in building stubs: */
2711           /* 1. Determine what argument registers need to relocated.  This */
2712           /*    step is already done here. */
2713           /* 2. Build the appropriate stub in the .hppa_linker_stubs section. */
2714           /*    This section should never appear in an object file.  It is */
2715           /*    only used internally.  The output_section of the */
2716           /*    .hppa_linker_stubs section is the .text section of the */
2717           /*    executable.     */
2718           /* 3. Build a symbol that is used (internally only) as the entry */
2719           /*    point of the stub. */
2720           /* 4. Change the instruction of the original branch into a branch to */
2721           /*    the stub routine. */
2722           /* 5. Build a relocation entry for the instruction of the original */
2723           /*    branch to be R_HPPA_PCREL_CALL to the stub routine. */
2724
2725
2726           if (stub_types[0]
2727               || stub_types[1]
2728               || stub_types[2]
2729               || stub_types[3]
2730               || stub_types[4])
2731             {
2732 #ifdef DETECT_STUBS
2733               int i;
2734
2735               fprintf (stderr, "Stub needed for %s @ %s+0x%x: callee/caller ar=0x%x/0x%x ",
2736                        reloc_entry->sym_ptr_ptr[0]->name,
2737                        abfd->filename, reloc_entry->address,
2738                        callee_ar, caller_ar);
2739               for (i = ARG0; i < RETVAL; i++)
2740                 {
2741                   if (stub_types[i] != NO_ARG_RELOC)
2742                     {
2743                       fprintf (stderr, "%s%d: %s ",
2744                                i == RETVAL ? "ret" : "arg",
2745                                i == RETVAL ? 0 : i,
2746                                reloc_type_strings[stub_types[i]]);
2747                     }
2748                 }
2749               fprintf (stderr, "\n");
2750 #endif
2751               return 1;
2752             }
2753
2754         }
2755     }
2756   return 0;
2757 }
2758
2759 asymbol *
2760 hppa_elf_build_long_branch_stub (abfd, output_bfd, link_info, reloc_entry,
2761                                  symbol, data)
2762      bfd *abfd;
2763      bfd *output_bfd;
2764      struct bfd_link_info *link_info;
2765      arelent *reloc_entry;
2766      asymbol *symbol;
2767      unsigned *data;
2768 {
2769   asection *stub_sec = bfd_get_section_by_name (abfd, ".hppa_linker_stubs");
2770   elf32_hppa_stub_description *stub_desc = find_stubs (abfd, stub_sec);
2771   asymbol *stub_sym = NULL;
2772   asymbol *target_sym = reloc_entry->sym_ptr_ptr[0];
2773   asection *output_text_section = bfd_get_section_by_name (output_bfd, ".text");
2774   char stub_sym_name[128];
2775   int milli = false;
2776   int dyncall = false;
2777   elf32_hppa_stub_name_list *stub_entry;
2778   int rtn_adjust = true;
2779   int rtn_reg;
2780   unsigned insn;
2781
2782   /* Create the stub section if it does not already exist.  */
2783   if (!stub_sec)
2784     {
2785       BFD_ASSERT (stub_desc == NULL);
2786       stub_sec = bfd_make_section (abfd, ".hppa_linker_stubs");
2787       bfd_set_section_flags (abfd,
2788                              stub_sec,
2789                              SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD
2790                              | SEC_RELOC | SEC_CODE | SEC_READONLY);
2791       stub_sec->output_section = output_text_section->output_section;
2792       stub_sec->output_offset = 0;
2793
2794       /* Set up the ELF section header for this new section.  This
2795          is basically the same processing as elf_make_sections().  
2796          elf_make_sections is static and therefore not accessable
2797          here.  */
2798       {
2799         Elf_Internal_Shdr *this_hdr;
2800         this_hdr = &elf_section_data (stub_sec)->this_hdr;
2801         
2802         /* Set the sizes of this section.  The contents have already
2803            been set up ?!?  */
2804         this_hdr->sh_addr = stub_sec->vma;
2805         this_hdr->sh_size = stub_sec->_raw_size;
2806         
2807         /* Set appropriate flags for sections with relocations.  */
2808         if (stub_sec->flags & SEC_RELOC)
2809           {
2810             Elf_Internal_Shdr *rela_hdr;
2811             int use_rela_p = get_elf_backend_data (abfd)->use_rela_p;
2812             
2813             rela_hdr = &elf_section_data (stub_sec)->rel_hdr;
2814             
2815             if (use_rela_p)
2816               {
2817                 rela_hdr->sh_type = SHT_RELA;
2818                 rela_hdr->sh_entsize = sizeof (Elf32_External_Rela);
2819               }
2820             else
2821               {
2822                 rela_hdr->sh_type = SHT_REL;
2823                 rela_hdr->sh_entsize = sizeof (Elf32_External_Rel);
2824               }
2825             rela_hdr->sh_flags = 0;
2826             rela_hdr->sh_addr = 0;
2827             rela_hdr->sh_offset = 0;
2828             rela_hdr->sh_addralign = 0;
2829             rela_hdr->size = 0;
2830           }
2831
2832         if (stub_sec->flags & SEC_ALLOC)
2833           {
2834             this_hdr->sh_flags |= SHF_ALLOC;
2835             /* FIXME.  If SEC_LOAD is true should we do something with
2836                with sh_type?  */
2837           }
2838
2839         if (!(stub_sec->flags & SEC_READONLY))
2840           this_hdr->sh_flags |= SHF_WRITE;
2841         
2842         if (stub_sec->flags & SEC_CODE)
2843           this_hdr->sh_flags |= SHF_EXECINSTR;
2844       }
2845       
2846       bfd_set_section_alignment (abfd, stub_sec, 2);
2847       stub_desc = new_stub (abfd, stub_sec, link_info);
2848     }
2849   
2850   if (!stub_desc)
2851     stub_desc = new_stub (abfd, stub_sec, link_info);
2852   
2853   /* Allocate memory to contain the stub.  FIXME.  Why isn't this using
2854      the BFD memory allocation routines?  */
2855   if (!stub_desc->stub_contents)
2856     {
2857       stub_desc->allocated_size = STUB_BUFFER_INCR;
2858       stub_desc->stub_contents = (char *) malloc (STUB_BUFFER_INCR);
2859     }
2860   else if ((stub_desc->allocated_size - stub_desc->real_size) < STUB_MAX_SIZE)
2861     {
2862       stub_desc->allocated_size = stub_desc->allocated_size + STUB_BUFFER_INCR;
2863       stub_desc->stub_contents = (char *) realloc (stub_desc->stub_contents,
2864                                                    stub_desc->allocated_size);
2865     }
2866   
2867   stub_desc->stub_secp
2868     = (int *) (stub_desc->stub_contents + stub_desc->real_size);
2869   
2870   /* Is this a millicode call?  If so, the return address
2871      comes in on r31 rather than r2 (rp) so a slightly
2872      different code sequence is needed.  */
2873   
2874   insn = data[0];
2875   rtn_reg = (insn & 0x03e00000) >> 21;
2876   if (rtn_reg == 31)
2877     milli = true;
2878   
2879   if (strcmp (symbol->name, "$$dyncall") == 0)
2880     dyncall = true;
2881
2882   /* If we are creating a call from a stub to another stub, then
2883      never do the instruction reordering.  We can tell if we are
2884      going to be calling one stub from another by the fact that
2885      the symbol name has '_stub_' (arg. reloc. stub) or '_lb_stub_'
2886      prepended to the name.  Alternatively, the section of the
2887      symbol will be '.hppa_linker_stubs'.  */
2888
2889   if ((strncmp (symbol->name, "_stub_", 6) == 0)
2890       || (strncmp (symbol->name, "_lb_stub_", 9) == 0))
2891     {
2892       BFD_ASSERT (strcmp (symbol->section->name, ".hppa_linker_stubs") == 0);
2893       rtn_adjust = false;
2894     }
2895   
2896   /* Check to see if we modify the return pointer
2897      in the delay slot of the branch.  */
2898   {
2899     unsigned delay_insn = data[1];
2900     
2901     /* If we nullify the delay slot, or if the delay slot contains an
2902        instruction that modifies the return pointer, then no additional
2903        modification of the return pointer is necessary.  */
2904     if (insn & 2 || insn == 0)
2905       rtn_adjust = false;
2906     else
2907       {
2908         if (get_opcode (delay_insn) == LDO
2909             && (((delay_insn & 0x001f0000) >> 16) == rtn_reg))
2910           rtn_adjust = false;
2911         if (milli)
2912           rtn_adjust = false;
2913       }
2914   }
2915   
2916   sprintf (stub_sym_name,
2917            "_lb_stub_%s_%s", reloc_entry->sym_ptr_ptr[0]->name,
2918            rtn_adjust ? "RA" : "");
2919   stub_entry = find_stub_by_name(abfd, stub_sec, stub_sym_name);
2920
2921   /* If a copy of this stub already exists re-use it.  */
2922   if (stub_entry)
2923     {
2924       stub_sym = stub_entry->sym;
2925
2926       /* Change symbol associated with the original relocation to point
2927          to the stub.
2928
2929          FIXME.  Is there a need to change the relocation type too?  */
2930       reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2931                                                           sizeof (asymbol *));
2932       reloc_entry->sym_ptr_ptr[0] = stub_sym;
2933       reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
2934     }
2935   else
2936     {
2937       /* We will need to allocate a new stub.  */
2938       stub_sym = bfd_make_empty_symbol (abfd);
2939       stub_sym->name = bfd_zalloc (abfd, strlen (stub_sym_name) + 1);
2940       strcpy ((char *) stub_sym->name, stub_sym_name);
2941       stub_sym->value
2942         = (int) stub_desc->stub_secp - (int) stub_desc->stub_contents;
2943       stub_sym->section = stub_sec;
2944       stub_sym->flags = BSF_LOCAL | BSF_FUNCTION;
2945       stub_entry = add_stub_by_name (abfd, stub_sec, stub_sym, link_info);
2946       
2947       /* Change symbol associated with the original relocation to point
2948          to the stub.
2949
2950          FIXME.  Is there a need to change the relocation type too?  */
2951       reloc_entry->sym_ptr_ptr = (asymbol **) bfd_zalloc (stub_desc->this_bfd,
2952                                                           sizeof (asymbol *));
2953       reloc_entry->sym_ptr_ptr[0] = stub_sym;
2954       reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
2955       
2956       /* Build the stub.  */
2957       
2958       /* 1. initialization for the call. */
2959       NEW_INSTRUCTION (stub_entry, LDSID_31_1);
2960       NEW_INSTRUCTION (stub_entry, MTSP_1_SR0);
2961       
2962       if (!dyncall)
2963         {
2964           if (!milli)
2965             {
2966               if (rtn_adjust)
2967                 {
2968                   NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
2969                 }
2970               else
2971                 {
2972                   NEW_INSTRUCTION (stub_entry, COPY_31_2);
2973                 }
2974             }
2975           else
2976             {
2977               if (rtn_adjust)
2978                 {
2979                   NEW_INSTRUCTION (stub_entry, ADDI_M4_31_1);
2980                 }
2981               else
2982                 {
2983                   NEW_INSTRUCTION (stub_entry, COPY_31_1);
2984                 }
2985             }
2986           
2987           NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
2988           hppa_elf_stub_reloc (stub_desc,
2989                                abfd,
2990                                target_sym,
2991                                CURRENT_STUB_OFFSET (stub_entry),
2992                                R_HPPA_L21);
2993           
2994           /* 2. Make the call. */
2995           if (!milli)
2996             {
2997               NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
2998               hppa_elf_stub_reloc (stub_desc,
2999                                    abfd,
3000                                    target_sym,
3001                                    CURRENT_STUB_OFFSET (stub_entry),
3002                                    R_HPPA_ABS_CALL_R17);
3003               NEW_INSTRUCTION (stub_entry, COPY_2_31);
3004             }
3005           else
3006             {
3007               NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
3008               hppa_elf_stub_reloc (stub_desc,
3009                                    abfd,
3010                                    target_sym,
3011                                    CURRENT_STUB_OFFSET (stub_entry),
3012                                    R_HPPA_ABS_CALL_R17);
3013               NEW_INSTRUCTION (stub_entry, COPY_1_31);
3014             }
3015         }
3016       else
3017         {
3018           /* 3. Branch back to the original location.
3019              (For non-millicode calls, this is accomplished with the
3020              COPY_31_2 instruction.  For millicode calls, the return
3021              location is already in r2.)  */
3022           if (rtn_adjust)
3023             {
3024               NEW_INSTRUCTION (stub_entry, ADDI_M4_31_RP);
3025             }
3026           NEW_INSTRUCTION (stub_entry, LDIL_XXX_31);
3027           hppa_elf_stub_reloc (stub_desc,
3028                                abfd,
3029                                target_sym,
3030                                CURRENT_STUB_OFFSET (stub_entry),
3031                                R_HPPA_L21);
3032           
3033           NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
3034           hppa_elf_stub_reloc (stub_desc,
3035                                abfd,
3036                                target_sym,
3037                                CURRENT_STUB_OFFSET (stub_entry),
3038                                R_HPPA_ABS_CALL_R17);
3039           NEW_INSTRUCTION (stub_entry, COPY_2_31);
3040         }
3041     }
3042   return stub_sym;
3043 }
3044
3045 int
3046 hppa_elf_long_branch_needed_p (abfd, asec, reloc_entry, symbol, insn)
3047      bfd *abfd;
3048      asection *asec;
3049      arelent *reloc_entry;
3050      asymbol *symbol;
3051      unsigned insn;
3052 {
3053   long sym_value = get_symbol_value(symbol);
3054   int fmt = reloc_entry->howto->bitsize;
3055   unsigned char op = get_opcode(insn);
3056   unsigned raddr;
3057
3058 #define too_far(val,num_bits)   ((int)(val) > (1<<(num_bits))-1) || ((int)(val) < (-1<<(num_bits)))
3059
3060   switch (op)
3061     {
3062     case BL:
3063       raddr =
3064         reloc_entry->address + asec->output_offset + asec->output_section->vma;
3065       if ( too_far(sym_value - raddr,fmt+1) )
3066         {
3067 #ifdef DETECT_STUBS
3068           fprintf(stderr,"long_branch needed on BL insn: abfd=%s,sym=%s,distance=0x%x\n",abfd->filename,symbol->name,sym_value - reloc_entry->address);
3069 #endif
3070           return 1;
3071         }
3072       break;
3073     }  
3074   return 0;
3075 }
3076
3077 #define STUB_SYM_BUFFER_INC     5
3078
3079 asymbol *
3080 hppa_look_for_stubs_in_section (stub_bfd, abfd, output_bfd, asec,
3081                                 syms, new_sym_cnt, link_info)
3082      bfd *stub_bfd;
3083      bfd *abfd;
3084      bfd *output_bfd;
3085      asection *asec;
3086      asymbol **syms;
3087      int *new_sym_cnt;
3088      struct bfd_link_info *link_info;
3089 {
3090   int i;
3091   int stub_types[5];
3092   asymbol *new_syms = (asymbol *) NULL;
3093   int new_cnt = 0;
3094   int new_max = 0;
3095
3096   /* Relocations are in different places depending on whether this is
3097      an output section or an input section.  Also, the relocations are
3098      in different forms.  Sigh.  Luckily, we have
3099      bfd_canonicalize_reloc() to straighten this out for us . */
3100
3101   if (asec->reloc_count > 0)
3102     {
3103       arelent **reloc_vector
3104         = (arelent **) alloca (asec->reloc_count * (sizeof (arelent *) + 1));
3105
3106       bfd_canonicalize_reloc (abfd, asec, reloc_vector, syms);
3107       for (i = 0; i < asec->reloc_count; i++)
3108         {
3109           arelent *rle = reloc_vector[i];
3110
3111           switch (rle->howto->type)
3112             {
3113             case R_HPPA_ABS_CALL_11:
3114             case R_HPPA_ABS_CALL_14:
3115             case R_HPPA_ABS_CALL_17:
3116             case R_HPPA_ABS_CALL_L21:
3117             case R_HPPA_ABS_CALL_R11:
3118             case R_HPPA_ABS_CALL_R14:
3119             case R_HPPA_ABS_CALL_R17:
3120             case R_HPPA_ABS_CALL_LS21:
3121             case R_HPPA_ABS_CALL_RS11:
3122             case R_HPPA_ABS_CALL_RS14:
3123             case R_HPPA_ABS_CALL_RS17:
3124             case R_HPPA_ABS_CALL_LD21:
3125             case R_HPPA_ABS_CALL_RD11:
3126             case R_HPPA_ABS_CALL_RD14:
3127             case R_HPPA_ABS_CALL_RD17:
3128             case R_HPPA_ABS_CALL_LR21:
3129             case R_HPPA_ABS_CALL_RR14:
3130             case R_HPPA_ABS_CALL_RR17:
3131             case R_HPPA_PCREL_CALL_11:
3132             case R_HPPA_PCREL_CALL_14:
3133             case R_HPPA_PCREL_CALL_17:
3134             case R_HPPA_PCREL_CALL_12:
3135             case R_HPPA_PCREL_CALL_L21:
3136             case R_HPPA_PCREL_CALL_R11:
3137             case R_HPPA_PCREL_CALL_R14:
3138             case R_HPPA_PCREL_CALL_R17:
3139             case R_HPPA_PCREL_CALL_LS21:
3140             case R_HPPA_PCREL_CALL_RS11:
3141             case R_HPPA_PCREL_CALL_RS14:
3142             case R_HPPA_PCREL_CALL_RS17:
3143             case R_HPPA_PCREL_CALL_LD21:
3144             case R_HPPA_PCREL_CALL_RD11:
3145             case R_HPPA_PCREL_CALL_RD14:
3146             case R_HPPA_PCREL_CALL_RD17:
3147             case R_HPPA_PCREL_CALL_LR21:
3148             case R_HPPA_PCREL_CALL_RR14:
3149             case R_HPPA_PCREL_CALL_RR17:
3150               {
3151                 symext_entryS caller_ar
3152                   = (symext_entryS) HPPA_R_ARG_RELOC (rle->addend);
3153                 unsigned insn[2];
3154
3155                 bfd_get_section_contents (abfd, asec, insn, rle->address,
3156                                           sizeof(insn));
3157                 if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types,
3158                                                  caller_ar))
3159                   {
3160                     /* Generate a stub and keep track of the new symbol.  */
3161                     asymbol *r;
3162
3163                     if (new_cnt == new_max)
3164                       {
3165                         new_max += STUB_SYM_BUFFER_INC;
3166                         new_syms = (asymbol *)
3167                           realloc (new_syms, new_max * sizeof (asymbol));
3168                       }
3169
3170                     /* The rtn_adjust argument is true here because we
3171                        know that we have a branch and (with a few exceptions
3172                        detailed under the relocation code for relocation type
3173                        R_HPPA_STUB_CALL_17) it will be possible to perform
3174                        the code reorientation.  */
3175                     r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
3176                                                        link_info, rle,
3177                                                        stub_types,
3178                                                        true, insn);
3179                     new_syms[new_cnt++] = *r;
3180                   }
3181
3182                 /* We need to retrieve the section contents to check for
3183                    long branch stubs.  */
3184                 if (hppa_elf_long_branch_needed_p (abfd, asec, rle,
3185                                                    rle->sym_ptr_ptr[0],
3186                                                    insn[0]))
3187                   {
3188                     /* Generate a stub and keep track of the new symbol.  */
3189                     asymbol *r;
3190
3191                     if (new_cnt == new_max)
3192                       {
3193                         new_max += STUB_SYM_BUFFER_INC;
3194                         new_syms = (asymbol *)
3195                           realloc (new_syms, (new_max * sizeof (asymbol)));
3196                       }
3197                     r = hppa_elf_build_long_branch_stub (stub_bfd, output_bfd,
3198                                                          link_info, rle,
3199                                                          rle->sym_ptr_ptr[0],
3200                                                          insn);
3201                     new_syms[new_cnt++] = *r;
3202                   }
3203               }
3204               break;
3205
3206             case R_HPPA_PLABEL_32:
3207             case R_HPPA_PLABEL_11:
3208             case R_HPPA_PLABEL_14:
3209             case R_HPPA_PLABEL_L21:
3210             case R_HPPA_PLABEL_R11:
3211             case R_HPPA_PLABEL_R14:
3212               {
3213                 /* On a plabel relocation, assume the arguments of the
3214                    caller are set up in general registers.
3215                    NOTE:  0x155 = ARGW0=CR,ARGW1=GR,ARGW2=GR,RETVAL=GR */
3216                 symext_entryS caller_ar = (symext_entryS) 0x155;
3217                 unsigned insn[2];
3218
3219                 bfd_get_section_contents (abfd, asec, insn, rle->address,
3220                                           sizeof(insn));
3221
3222                 if (hppa_elf_arg_reloc_needed_p (abfd, rle, stub_types,
3223                                                  caller_ar))
3224                   {
3225                     /* Generate a plabel stub and keep track of the
3226                        new symbol.  */
3227                     asymbol *r;
3228                     int rtn_adjust;
3229
3230                     if (new_cnt == new_max)
3231                       {
3232                         new_max += STUB_SYM_BUFFER_INC;
3233                         new_syms = (asymbol *) realloc (new_syms, new_max
3234                                                         * sizeof (asymbol));
3235                       }
3236
3237                     /* Determine whether a return adjustment
3238                        (see the relocation code for relocation type 
3239                        R_HPPA_STUB_CALL_17) is possible.  Basically,
3240                        determine whether we are looking at a branch or not.  */
3241                                                               
3242                     if (rle->howto->type == R_HPPA_PLABEL_32)
3243                       rtn_adjust = false;
3244                     else
3245                       {
3246                         switch (get_opcode(insn[0]))
3247                           {
3248                           case BLE:
3249                           case BE:
3250                             rtn_adjust = true;
3251                             break;
3252                           default:
3253                             rtn_adjust = false;
3254                           }
3255                       }
3256                     r = hppa_elf_build_arg_reloc_stub (stub_bfd, output_bfd,
3257                                                        link_info, rle,
3258                                                        stub_types,
3259                                                        rtn_adjust, insn);
3260                     new_syms[new_cnt++] = *r;
3261                   }
3262               }
3263               break;
3264
3265             default:
3266               break;
3267
3268             }
3269         }
3270     }
3271   *new_sym_cnt = new_cnt;
3272   return new_syms;
3273 }
3274
3275
3276 char *linker_stubs = NULL;
3277 int linker_stubs_size = 0;
3278 int linker_stubs_max_size = 0;
3279 #define STUB_ALLOC_INCR 100
3280
3281 boolean
3282 hppa_elf_set_section_contents (abfd, section, location, offset, count)
3283      bfd *abfd;
3284      sec_ptr section;
3285      PTR location;
3286      file_ptr offset;
3287      bfd_size_type count;
3288 {
3289   if ( strcmp(section->name, ".hppa_linker_stubs") == 0 )
3290     {
3291       if ( linker_stubs_max_size < offset + count )
3292         {
3293           linker_stubs_max_size = offset + count + STUB_ALLOC_INCR;
3294           linker_stubs = (char *)realloc(linker_stubs, linker_stubs_max_size);
3295         }
3296
3297       if ( offset + count > linker_stubs_size )
3298         linker_stubs_size = offset + count;
3299
3300       memcpy(linker_stubs + offset,location,count);
3301       return (true);
3302     }
3303   else
3304     return bfd_elf32_set_section_contents (abfd, section, location,
3305                                            offset, count);
3306 }
3307
3308 /* Get the contents of the given section.
3309    
3310    This is special for PA ELF because some sections (such as linker stubs)
3311    may reside in memory rather than on disk, or in the case of the symbol
3312    extension section, the contents may need to be generated from other
3313    information contained in the BFD.  */
3314
3315 boolean
3316 hppa_elf_get_section_contents (abfd, section, location, offset, count)
3317      bfd *abfd;
3318      sec_ptr section;
3319      PTR location;
3320      file_ptr offset;
3321      bfd_size_type count;
3322 {
3323   /* If this is the linker stub section, then its contents are contained
3324      in memory rather than on disk.  FIXME.  Is that always right?  What
3325      about the case where a final executable is read in and a user tries
3326      to get the contents of this section?  In that case the contents would
3327      be on disk like everything else.  */
3328   if (strcmp (section->name, ".hppa_linker_stubs") == 0)
3329     {
3330       elf32_hppa_stub_description *stub_desc = find_stubs (abfd, section);
3331       
3332       if (count == 0)
3333         return true;
3334       
3335       /* Sanity check our arguments.  */
3336       if ((bfd_size_type) (offset + count) > section->_raw_size
3337           || (bfd_size_type) (offset + count) > stub_desc->real_size)
3338         return (false);
3339       
3340       memcpy (location, stub_desc->stub_contents + offset, count);
3341       return (true);
3342     }
3343
3344   /* The symbol extension section also needs special handling.  Its
3345      contents might be on the disk, in memory, or still need to
3346      be generated. */
3347   else if (strcmp (section->name, ".hppa_symextn") == 0)
3348     {
3349       /* If there are no output sections, then read the contents of the
3350          symbol extension section from disk.  */
3351       if (section->output_section == NULL
3352           && abfd->direction == read_direction)
3353         {
3354           return bfd_generic_get_section_contents (abfd, section, location,
3355                                                    offset, count);
3356         }
3357       
3358       /* If this is the first time through, and there are output sections,
3359          then build the symbol extension section based on other information
3360          contained in the BFD.  */
3361       else if (! symext_chain_built)
3362         {
3363           int i;
3364           int *symtab_map =
3365             (int *) elf_sym_extra(section->output_section->owner);
3366           
3367           for (i = 0; i < section->output_section->owner->symcount; i++ )
3368             {
3369               elf_hppa_tc_symbol(section->output_section->owner,
3370                                  ((elf_symbol_type *)
3371                                   section->output_section->owner->outsymbols[i]),
3372                                  symtab_map[i]);
3373             }
3374           symext_chain_built++;
3375           elf_hppa_tc_make_sections (section->output_section->owner, NULL);
3376         }
3377
3378       /* At this point we know that the symbol extension section has been
3379          built.  We just need to copy it into the user's buffer.  */
3380       if (count == 0)
3381         return true;
3382       
3383       /* Sanity check our arguments.  */
3384       if ((bfd_size_type) (offset + count) > section->_raw_size
3385           || (bfd_size_type) (offset + count) > symextn_contents_real_size)
3386         return (false);
3387       
3388       memcpy (location,
3389               ((char *)symextn_contents + section->output_offset + offset),
3390               count);
3391       return (true);
3392     }
3393   else
3394     return bfd_generic_get_section_contents (abfd, section, location,
3395                                              offset, count);
3396 }
3397
3398 static void
3399 elf_info_to_howto (abfd, cache_ptr, dst)
3400      bfd *abfd;
3401      arelent *cache_ptr;
3402      Elf32_Internal_Rela *dst;
3403 {
3404   BFD_ASSERT (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_HPPA_UNIMPLEMENTED);
3405   cache_ptr->howto = &elf_hppa_howto_table[ELF32_R_TYPE(dst->r_info)];
3406 }
3407
3408 static void
3409 elf32_hppa_backend_symbol_processing (abfd, sym)
3410      bfd *abfd;
3411      asymbol *sym;
3412 {
3413   /* Is this a definition of $global$?  If so, keep it because it will be
3414     needed if any relocations are performed.  */
3415
3416   if (!strcmp (sym->name, "$global$")
3417       && sym->section != &bfd_und_section)
3418     {
3419       global_symbol = sym;
3420     }
3421 }
3422
3423 #define elf_backend_symbol_processing   elf32_hppa_backend_symbol_processing
3424
3425 struct elf32_hppa_symextn_map_struct
3426 {
3427   int old_index;
3428   bfd *bfd;
3429   asymbol *sym;
3430   int new_index;
3431 };
3432
3433 static struct elf32_hppa_symextn_map_struct *elf32_hppa_symextn_map;
3434 static int elf32_hppa_symextn_map_size;
3435
3436 static boolean
3437 elf32_hppa_backend_symbol_table_processing (abfd, esyms,symcnt)
3438      bfd *abfd;
3439      elf_symbol_type *esyms;
3440      int symcnt;
3441 {
3442   Elf32_Internal_Shdr *symextn_hdr = bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME);
3443   int i;
3444   int current_sym_idx = 0;
3445
3446   /* If the symbol extension section does not exist, all the symbol */
3447   /* all the symbol extension information is assumed to be zero.        */
3448
3449   if ( symextn_hdr == NULL )
3450     {
3451       for ( i = 0; i < symcnt; i++ )
3452         {
3453           esyms[i].tc_data.hppa_arg_reloc = 0;
3454         }
3455       return (true);
3456     }
3457
3458   /* allocate a buffer of the appropriate size for the symextn section */
3459
3460   symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size);
3461   symextn_hdr->size = symextn_hdr->sh_size;
3462         
3463   /* read in the symextn section */
3464
3465   if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1)
3466     {
3467       bfd_error = system_call_error;
3468       return (false);
3469     }
3470   if (bfd_read ((PTR) symextn_hdr->contents, 1, symextn_hdr->size, abfd) 
3471       != symextn_hdr->size)
3472     {
3473       free ((PTR)symextn_hdr->contents);
3474       bfd_error = system_call_error;
3475       return (false);
3476     }   
3477
3478   /* parse the entries, updating the symtab entries as we go */
3479
3480   for ( i = 0; i < symextn_hdr->size / sizeof(symext_entryS); i++ )
3481     {
3482       symext_entryS *seP = ((symext_entryS *)symextn_hdr->contents) + i;
3483       int se_value = ELF32_HPPA_SX_VAL(*seP);
3484       int se_type = ELF32_HPPA_SX_TYPE(*seP);
3485
3486       switch ( se_type )
3487         {
3488         case HPPA_SXT_NULL:
3489           break;
3490
3491         case HPPA_SXT_SYMNDX:
3492           if ( se_value >= symcnt )
3493             {
3494               bfd_error = bad_value;
3495               bfd_perror("elf32_hppa_backend_symbol_table_processing -- symbol index");
3496               return (false);
3497             }
3498           current_sym_idx = se_value - 1;
3499           break;
3500
3501         case HPPA_SXT_ARG_RELOC:
3502           esyms[current_sym_idx].tc_data.hppa_arg_reloc = se_value;
3503           break;
3504
3505         default:
3506           bfd_error = bad_value;
3507           bfd_perror("elf32_hppa_backend_symbol_table_processing");
3508           return (false);
3509         }
3510     }
3511   return (true);
3512 }
3513
3514 #define elf_backend_symbol_table_processing     elf32_hppa_backend_symbol_table_processing
3515
3516 static boolean
3517 elf32_hppa_backend_section_processing (abfd, secthdr)
3518      bfd *abfd;
3519      Elf32_Internal_Shdr *secthdr;
3520 {
3521   int i,j,k;
3522
3523   if ( secthdr->sh_type == SHT_HPPA_SYMEXTN )
3524     {
3525       for ( i = 0; i < secthdr->size / sizeof(symext_entryS); i++ )
3526         {
3527           symext_entryS *seP = ((symext_entryS *)secthdr->contents) + i;
3528           int se_value = ELF32_HPPA_SX_VAL(*seP);
3529           int se_type = ELF32_HPPA_SX_TYPE(*seP);
3530           
3531           switch ( se_type )
3532             {
3533             case HPPA_SXT_NULL:
3534               break;
3535               
3536             case HPPA_SXT_SYMNDX:
3537               for ( j = 0; j < abfd->symcount; j++ )
3538                 {
3539                   /* locate the map entry for this symbol, if there is one. */
3540                   /* modify the symbol extension section symbol index entry */
3541                   /* to reflect the new symbol table index */
3542                   
3543                   for ( k = 0; k < elf32_hppa_symextn_map_size; k++ )
3544                     {
3545                       if ( elf32_hppa_symextn_map[k].old_index == se_value
3546                           && elf32_hppa_symextn_map[k].bfd == abfd->outsymbols[j]->the_bfd
3547                           && elf32_hppa_symextn_map[k].sym == abfd->outsymbols[j] )
3548                         {
3549                           bfd_put_32(abfd,
3550                                      ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, j),
3551                                      (char *)seP);
3552                         }
3553                     }
3554                 }
3555               break;
3556               
3557             case HPPA_SXT_ARG_RELOC:
3558               break;
3559               
3560             default:
3561               bfd_error = bad_value;
3562               bfd_perror("elf32_hppa_backend_section_processing");
3563               return (false);
3564             }
3565         }
3566     }
3567   return true;
3568 }
3569
3570 #define elf_backend_section_processing  elf32_hppa_backend_section_processing
3571
3572 static boolean
3573 elf32_hppa_backend_section_from_shdr (abfd, hdr, name)
3574      bfd *abfd;
3575      Elf32_Internal_Shdr *hdr;
3576      char *name;
3577 {
3578   asection *newsect;
3579
3580   if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
3581     {
3582       BFD_ASSERT ( strcmp(name,".hppa_symextn") == 0 );
3583
3584       /* Bits that get saved. This one is real. */
3585       if (!hdr->rawdata)
3586         {
3587           newsect = bfd_make_section (abfd, name);
3588           if (newsect != NULL)
3589             {
3590               newsect->vma = hdr->sh_addr;
3591               newsect->_raw_size = hdr->sh_size;
3592               newsect->filepos = hdr->sh_offset;        /* so we can read back the bits */
3593               newsect->flags |= SEC_HAS_CONTENTS;
3594               newsect->alignment_power = hdr->sh_addralign;
3595
3596               if (hdr->sh_flags & SHF_ALLOC)
3597                 {
3598                   newsect->flags |= SEC_ALLOC;
3599                   newsect->flags |= SEC_LOAD;
3600                 }
3601
3602               if (!(hdr->sh_flags & SHF_WRITE))
3603                 newsect->flags |= SEC_READONLY;
3604
3605               if (hdr->sh_flags & SHF_EXECINSTR)
3606                 newsect->flags |= SEC_CODE;     /* FIXME: may only contain SOME code */
3607               else
3608                 newsect->flags |= SEC_DATA;
3609
3610               hdr->rawdata = (void *) newsect;
3611             }
3612         }
3613       return true;
3614     }
3615   return false;
3616 }
3617
3618 #define elf_backend_section_from_shdr   elf32_hppa_backend_section_from_shdr
3619
3620 static boolean
3621 elf32_hppa_backend_fake_sections (abfd, secthdr, asect)
3622      bfd *abfd;
3623      Elf_Internal_Shdr *secthdr;
3624      asection *asect;
3625 {
3626
3627   if ( strcmp(asect->name, ".hppa_symextn") == 0 )
3628     {
3629       secthdr->sh_type = SHT_HPPA_SYMEXTN;
3630       secthdr->sh_flags = 0;
3631       secthdr->sh_info = elf_section_data(asect)->rel_hdr.sh_link;
3632       secthdr->sh_link = elf_onesymtab(abfd);
3633       return true;
3634     }
3635
3636   if (!strcmp (asect->name, ".hppa_unwind"))
3637     {
3638       secthdr->sh_type = SHT_PROGBITS;
3639       /* Unwind descriptors are not part of the program memory image.  */
3640       secthdr->sh_flags = 0;
3641       secthdr->sh_info = 0;
3642       secthdr->sh_link = 0;
3643       secthdr->sh_entsize = 16;
3644       return true;
3645     }
3646
3647   /* @@ Should this be CPU specific??  KR */
3648   if (!strcmp (asect->name, ".stabstr"))
3649     {
3650       secthdr->sh_type = SHT_STRTAB;
3651       secthdr->sh_flags = 0;
3652       secthdr->sh_info = 0;
3653       secthdr->sh_link = 0;
3654       secthdr->sh_entsize = 0;
3655       return true;
3656     }
3657
3658   return false;
3659 }
3660
3661 #define elf_backend_fake_sections       elf32_hppa_backend_fake_sections
3662
3663 static boolean
3664 elf32_hppa_backend_section_from_bfd_section (abfd, hdr, asect, retval)
3665      bfd *abfd;
3666      Elf32_Internal_Shdr *hdr;
3667      asection *asect;
3668      int *retval;
3669 {
3670   if ( hdr->sh_type == SHT_HPPA_SYMEXTN )
3671     {
3672       if (hdr->rawdata)
3673         {
3674           if (((struct sec *) (hdr->rawdata)) == asect)
3675             {
3676               BFD_ASSERT( strcmp(asect->name, ".hppa_symextn") == 0 );
3677               return true;
3678             }
3679         }
3680     }
3681   else if ( hdr->sh_type == SHT_STRTAB )
3682     {
3683       if (hdr->rawdata)
3684         {
3685           if (((struct sec *) (hdr->rawdata)) == asect)
3686             {
3687               BFD_ASSERT ( strcmp (asect->name, ".stabstr") == 0);
3688               return true;
3689             }
3690         }
3691     }
3692
3693   return false;
3694 }
3695
3696 #define elf_backend_section_from_bfd_section    elf32_hppa_backend_section_from_bfd_section
3697
3698 #define bfd_generic_get_section_contents        hppa_elf_get_section_contents
3699 #define bfd_elf32_set_section_contents          hppa_elf_set_section_contents
3700
3701 #define TARGET_BIG_SYM          bfd_elf32_hppa_vec
3702 #define TARGET_BIG_NAME         "elf32-hppa"
3703 #define ELF_ARCH                bfd_arch_hppa
3704 #define ELF_MACHINE_CODE        EM_HPPA
3705 #define ELF_MAXPAGESIZE         0x1000
3706
3707 #include "elf32-target.h"
This page took 0.24034 seconds and 4 git commands to generate.