]> Git Repo - binutils.git/blob - gold/i386.cc
Snapshot. Now able to produce a minimal executable which actually
[binutils.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.
This page took 0.03259 seconds and 4 git commands to generate.