]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gold/i386.cc
Snapshot. Now able to produce a minimal executable which actually
[thirdparty/binutils-gdb.git] / gold / i386.cc
1 // i386.cc -- i386 target support for gold.
2
3 #include "gold.h"
4 #include "elfcpp.h"
5 #include "i386.h"
6 #include "object.h"
7 #include "target.h"
8 #include "target-reloc.h"
9 #include "target-select.h"
10
11 namespace
12 {
13
14 using namespace gold;
15
16 // The i386 target class.
17
18 class Target_i386 : public Sized_target<32, false>
19 {
20 public:
21 Target_i386()
22 : Sized_target<32, false>(&i386_info)
23 { }
24
25 void
26 relocate_section(const Symbol_table* symtab,
27 Sized_object<32, false>*,
28 unsigned int,
29 const unsigned char*,
30 size_t,
31 unsigned int,
32 const elfcpp::Elf_types<32>::Elf_Addr*,
33 Symbol**,
34 unsigned char*,
35 elfcpp::Elf_types<32>::Elf_Addr,
36 off_t);
37
38 // The class which implements relocation.
39 struct Relocate
40 {
41 inline void
42 operator()(Sized_object<32, false>*, const elfcpp::Rel<32, false>&,
43 unsigned int r_type, Sized_symbol<32>*,
44 elfcpp::Elf_types<32>::Elf_Addr,
45 unsigned char*, elfcpp::Elf_types<32>::Elf_Addr);
46
47 };
48
49 private:
50 static const Target::Target_info i386_info;
51 };
52
53 const Target::Target_info Target_i386::i386_info =
54 {
55 32, // size
56 false, // is_big_endian
57 elfcpp::EM_386, // machine_code
58 false, // has_make_symbol
59 false, // has_resolve,
60 0x08048000, // text_segment_address,
61 0x1000, // abi_pagesize
62 0x1000 // common_pagesize
63 };
64
65 // Perform a relocation.
66
67 inline void
68 Target_i386::Relocate::operator()(Sized_object<32, false>* object,
69 const elfcpp::Rel<32, false>&,
70 unsigned int r_type,
71 Sized_symbol<32>*,
72 elfcpp::Elf_types<32>::Elf_Addr value,
73 unsigned char* view,
74 elfcpp::Elf_types<32>::Elf_Addr address)
75 {
76 switch (r_type)
77 {
78 case elfcpp::R_386_NONE:
79 break;
80
81 case elfcpp::R_386_32:
82 {
83 elfcpp::Elf_Word* wv = reinterpret_cast<elfcpp::Elf_Word*>(view);
84 unsigned int x = elfcpp::read_elf_word<false>(wv);
85 elfcpp::write_elf_word<false>(wv, x + value);
86 }
87 break;
88
89 case elfcpp::R_386_PC32:
90 {
91 elfcpp::Elf_Word* wv = reinterpret_cast<elfcpp::Elf_Word*>(view);
92 unsigned int x = elfcpp::read_elf_word<false>(wv);
93 elfcpp::write_elf_word<false>(wv, x + value - address);
94 }
95 break;
96
97 default:
98 fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
99 program_name, object->name().c_str(), r_type);
100 // gold_exit(false);
101 }
102 }
103
104 // Relocate section data.
105
106 void
107 Target_i386::relocate_section(const Symbol_table* symtab,
108 Sized_object<32, false>* object,
109 unsigned int sh_type,
110 const unsigned char* prelocs,
111 size_t reloc_count,
112 unsigned int local_count,
113 const elfcpp::Elf_types<32>::Elf_Addr* values,
114 Symbol** global_syms,
115 unsigned char* view,
116 elfcpp::Elf_types<32>::Elf_Addr address,
117 off_t view_size)
118 {
119 if (sh_type == elfcpp::SHT_RELA)
120 {
121 fprintf(stderr, _("%s: %s: unsupported RELA reloc section\n"),
122 program_name, object->name().c_str());
123 gold_exit(false);
124 }
125
126 gold::relocate_section<32, false, elfcpp::SHT_REL, Target_i386::Relocate>(
127 symtab,
128 object,
129 prelocs,
130 reloc_count,
131 local_count,
132 values,
133 global_syms,
134 view,
135 address,
136 view_size);
137 }
138
139 // The i386 target.
140
141 Target_i386 target_i386;
142
143 // The selector for i386 object files.
144
145 class Target_selector_i386 : public Target_selector
146 {
147 public:
148 Target_selector_i386()
149 : Target_selector(elfcpp::EM_386, 32, false)
150 { }
151
152 Target*
153 recognize(int machine, int osabi, int abiversion) const;
154 };
155
156 // Recognize an i386 object file when we already know that the machine
157 // number is EM_386.
158
159 Target*
160 Target_selector_i386::recognize(int, int, int) const
161 {
162 return &target_i386;
163 }
164
165 Target_selector_i386 target_selector_i386;
166
167 } // End anonymous namespace.