1 #ifndef _library__assembler__hpp__included__
2 #define _library__assembler__hpp__included__
5 #include "serialization.hpp"
15 typedef size_t addr_t
;
26 addr
= (addr_t
)global
;
28 label(const label
& _base
, int off
)
37 offset
= _base
.offset
+ off
;
41 addr
= _base
.addr
+ off
;
46 offset
= _base
.offset
+ off
;
54 throw std::runtime_error("Not undefined local label");
58 addr_t
resolve(addr_t localbase
) const
61 case L_LOCAL_U
: throw std::runtime_error("Unresolved label");
62 case L_LOCAL_R
: return localbase
+ offset
;
63 case L_GLOBAL
: return addr
;
64 case L_RELATIVE
: return base
->resolve(localbase
) + offset
;
66 throw std::runtime_error("Unknown relocation type");
69 enum _kind
{ L_LOCAL_U
, L_LOCAL_R
, L_GLOBAL
, L_RELATIVE
} kind
;
70 const struct label
* base
;
80 label
& external(void* addr
);
82 std::list
<label
> labels
;
85 void i386_reloc_rel8(uint8_t* location
, size_t target
, size_t source
);
86 void i386_reloc_rel16(uint8_t* location
, size_t target
, size_t source
);
87 void i386_reloc_rel32(uint8_t* location
, size_t target
, size_t source
);
88 void i386_reloc_abs32(uint8_t* location
, size_t target
, size_t source
);
89 void i386_reloc_abs64(uint8_t* location
, size_t target
, size_t source
);
90 uint8_t i386_modrm(uint8_t reg
, uint8_t mod
, uint8_t rm
);
91 uint8_t i386_sib(uint8_t base
, uint8_t index
, uint8_t scale
);
95 pad_tag(size_t _amount
) : amount(_amount
) {}
101 label_tag(label
& _l
) : l(_l
) {}
105 struct relocation_tag
107 relocation_tag(std::function
<void(uint8_t* location
, size_t target
, size_t source
)> _promise
,
108 const label
& _target
) : promise(_promise
), target(_target
) {}
109 std::function
<void(uint8_t* location
, size_t target
, size_t source
)> promise
;
115 byteseq_tag(const uint8_t* ss
, size_t _sl
) { st
.resize(_sl
); memcpy(&st
[0], ss
, _sl
); }
116 std::vector
<uint8_t> st
;
119 template<typename T
> byteseq_tag
vle(T v
)
121 uint8_t b
[sizeof(T
)];
122 serialization::write_common
<T
, false>(b
, v
);
123 return byteseq_tag(b
, sizeof(T
));
126 template<typename T
> byteseq_tag
vbe(T v
)
128 uint8_t b
[sizeof(T
)];
129 serialization::write_common
<T
, true>(b
, v
);
130 return byteseq_tag(b
, sizeof(T
));
136 template<typename
... T
> void operator()(uint8_t b
, T
... args
)
141 template<typename
... T
> void operator()(pad_tag p
, T
... args
)
146 template<typename
... T
> void operator()(label_tag l
, T
... args
)
151 template<typename
... T
> void operator()(relocation_tag r
, T
... args
)
153 relocation(r
.promise
, r
.target
);
156 template<typename
... T
> void operator()(byteseq_tag b
, T
... args
)
160 memcpy(&data
[o
], &b
.st
[0], b
.st
.size());
165 void _label(label
& l
);
166 void _label(label
& l
, const std::string
& globalname
);
167 void byte(uint8_t b
);
168 void byte(std::initializer_list
<uint8_t> b
);
169 void byte(const uint8_t* b
, size_t l
);
170 void relocation(std::function
<void(uint8_t* location
, size_t target
, size_t source
)> promise
,
171 const label
& target
);
172 void align(size_t multiple
);
173 void pad(size_t amount
);
175 void dump(const std::string
& basename
, const std::string
& name
, void* base
, std::map
<std::string
, void*> map
);
176 std::map
<std::string
, void*> flush(void* base
);
180 std::function
<void(uint8_t* location
, size_t target
, size_t source
)> promise
;
184 std::vector
<uint8_t> data
;
185 std::list
<reloc
> relocs
;
186 std::map
<std::string
, const label
*> globals
;
192 dynamic_code(size_t size
);
195 uint8_t* pointer() throw();