mirror of
https://github.com/ksherlock/merlin-utils.git
synced 2024-06-14 23:29:27 +00:00
ORG and LKV 1 support (untested)
This commit is contained in:
parent
34523bbecf
commit
637df6ee33
21
link.cpp
21
link.cpp
|
@ -31,6 +31,8 @@
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
|
||||||
void save_omf(const std::string &path, std::vector<omf::segment> &segments, bool compress, bool expressload);
|
void save_omf(const std::string &path, std::vector<omf::segment> &segments, bool compress, bool expressload);
|
||||||
|
void save_bin(const std::string &path, omf::segment &segment, uint32_t org);
|
||||||
|
|
||||||
int set_file_type(const std::string &path, uint16_t file_type, uint32_t aux_type, std::error_code &ec);
|
int set_file_type(const std::string &path, uint16_t file_type, uint32_t aux_type, std::error_code &ec);
|
||||||
void set_file_type(const std::string &path, uint16_t file_type, uint32_t aux_type);
|
void set_file_type(const std::string &path, uint16_t file_type, uint32_t aux_type);
|
||||||
|
|
||||||
|
@ -594,8 +596,14 @@ void finish(void) {
|
||||||
std::string path = save_file;
|
std::string path = save_file;
|
||||||
|
|
||||||
if (path.empty()) path = "gs.out";
|
if (path.empty()) path = "gs.out";
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
save_omf(path, segments, compress, express);
|
if (lkv == 0)
|
||||||
|
save_bin(path, segments.back(), org);
|
||||||
|
else
|
||||||
|
save_omf(path, segments, compress, express);
|
||||||
|
|
||||||
set_file_type(path, ftype, atype);
|
set_file_type(path, ftype, atype);
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
errx(EX_OSERR, "%s: %s", path.c_str(), ex.what());
|
errx(EX_OSERR, "%s: %s", path.c_str(), ex.what());
|
||||||
|
@ -743,6 +751,12 @@ void evaluate(label_t label, opcode_t opcode, const char *cursor) {
|
||||||
case OP_ADR:
|
case OP_ADR:
|
||||||
atype = number_operand(cursor, local_symbol_table);
|
atype = number_operand(cursor, local_symbol_table);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OP_ORG:
|
||||||
|
org = number_operand(cursor, local_symbol_table);
|
||||||
|
atype = org;
|
||||||
|
break;
|
||||||
|
|
||||||
case OP_KND: {
|
case OP_KND: {
|
||||||
uint32_t kind = number_operand(cursor, local_symbol_table);
|
uint32_t kind = number_operand(cursor, local_symbol_table);
|
||||||
if (!segments.empty())
|
if (!segments.empty())
|
||||||
|
@ -773,8 +787,8 @@ void evaluate(label_t label, opcode_t opcode, const char *cursor) {
|
||||||
|
|
||||||
uint32_t value = number_operand(cursor, local_symbol_table);
|
uint32_t value = number_operand(cursor, local_symbol_table);
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 0: throw std::runtime_error("binary linker not supported");
|
|
||||||
case 3: throw std::runtime_error("object file linker not supported");
|
case 3: throw std::runtime_error("object file linker not supported");
|
||||||
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
lkv = value;
|
lkv = value;
|
||||||
|
@ -841,7 +855,8 @@ void evaluate(label_t label, opcode_t opcode, const char *cursor) {
|
||||||
seg.loadname = base;
|
seg.loadname = base;
|
||||||
// seg.kind = kind;
|
// seg.kind = kind;
|
||||||
}
|
}
|
||||||
if (lkv == 1) {
|
|
||||||
|
if (lkv == 0 || lkv == 1) {
|
||||||
finish();
|
finish();
|
||||||
// reset. could have another link afterwards.
|
// reset. could have another link afterwards.
|
||||||
segments.clear();
|
segments.clear();
|
||||||
|
|
32
omf.cpp
32
omf.cpp
|
@ -351,6 +351,38 @@ uint32_t add_relocs(std::vector<uint8_t> &data, size_t data_offset, omf::segment
|
||||||
return reloc_size;
|
return reloc_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void save_bin(const std::string &path, omf::segment &segment, uint32_t org) {
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
|
||||||
|
if (fd < 0) {
|
||||||
|
err(EX_CANTCREAT, "Unable to open %s", path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &data = segment.data;
|
||||||
|
|
||||||
|
for (auto &r : segment.relocs) {
|
||||||
|
|
||||||
|
uint32_t value = r.value + org;
|
||||||
|
value >>= -(int8_t)r.shift;
|
||||||
|
|
||||||
|
unsigned offset = r.offset;
|
||||||
|
unsigned size = r.size;
|
||||||
|
while (size--) {
|
||||||
|
data[offset++] = value & 0xff;
|
||||||
|
value >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ok = write(fd, data.data(), data.size());
|
||||||
|
if (ok < 0) {
|
||||||
|
close(fd);
|
||||||
|
err(EX_OSERR, "write %s", path.c_str());
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void save_omf(const std::string &path, std::vector<omf::segment> &segments, bool compress, bool expressload) {
|
void save_omf(const std::string &path, std::vector<omf::segment> &segments, bool compress, bool expressload) {
|
||||||
|
|
||||||
// expressload doesn't support links to other files.
|
// expressload doesn't support links to other files.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user