Remove unused section writer
This commit is contained in:
parent
6d5cf23157
commit
7979c0cd23
@ -5,7 +5,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
find_package(Boost COMPONENTS program_options REQUIRED)
|
||||
find_package(Boost COMPONENTS process program_options REQUIRED)
|
||||
find_package(FLEX)
|
||||
include_directories(${Boost_INCLUDE_DIR})
|
||||
|
||||
|
@ -1,90 +1,14 @@
|
||||
#include "elna/backend/target.hpp"
|
||||
#include "elna/backend/riscv.hpp"
|
||||
#include <cstring>
|
||||
#include <boost/process/v2.hpp>
|
||||
#include <boost/endian.hpp>
|
||||
|
||||
namespace elna::riscv
|
||||
{
|
||||
elfio_section_writer::iterator::reference elfio_section_writer::iterator::operator*() const noexcept
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator::pointer elfio_section_writer::iterator::operator->() const noexcept
|
||||
{
|
||||
return &payload;
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator& elfio_section_writer::iterator::operator++()
|
||||
{
|
||||
this->payload.data += *this->sizes;
|
||||
this->payload.label = *(++this->labels);
|
||||
this->payload.size = *(++this->sizes);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator& elfio_section_writer::iterator::operator++(int)
|
||||
{
|
||||
auto tmp = *this;
|
||||
++(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool elfio_section_writer::iterator::operator==(const iterator& that) const
|
||||
{
|
||||
return this->labels == that.labels;
|
||||
}
|
||||
|
||||
bool elfio_section_writer::iterator::operator!=(const iterator& that) const
|
||||
{
|
||||
return !(*this == that);
|
||||
}
|
||||
|
||||
elfio_section_writer::elfio_section_writer(ELFIO::section *section)
|
||||
: m_section(section)
|
||||
{
|
||||
}
|
||||
|
||||
void elfio_section_writer::operator()(const std::string& label, const std::byte *data, std::size_t size)
|
||||
{
|
||||
labels.push_back(label);
|
||||
sizes.push_back(size);
|
||||
m_section->append_data(reinterpret_cast<const char *>(data), size);
|
||||
}
|
||||
|
||||
std::pair<std::string_view, bool> elfio_section_writer::operator()(const std::byte *data, std::size_t size)
|
||||
{
|
||||
auto found = std::find_if(begin(), end(),
|
||||
[data, size](elfio_section_writer::entry entry) {
|
||||
return size == entry.size && std::memcmp(entry.data, data, size) == 0;
|
||||
});
|
||||
if (found == end())
|
||||
{
|
||||
(*this)(".CL" + std::to_string(labels.size()), data, size);
|
||||
return std::pair<std::string_view, bool>(labels.back(), true);
|
||||
}
|
||||
return std::pair<std::string_view, bool>(found->label, false);
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator elfio_section_writer::begin() const
|
||||
{
|
||||
return elfio_section_writer::iterator(labels.cbegin(), sizes.cbegin(),
|
||||
reinterpret_cast<const std::byte *>(m_section->get_data()));
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator elfio_section_writer::end() const
|
||||
{
|
||||
return elfio_section_writer::iterator(labels.cend(), sizes.cend());
|
||||
}
|
||||
|
||||
ELFIO::section *elfio_section_writer::section() noexcept
|
||||
{
|
||||
return m_section;
|
||||
}
|
||||
|
||||
elfio_writer::elfio_writer(ELFIO::section *text, ELFIO::section *read_only,
|
||||
elfio_writer::elfio_writer(ELFIO::section *text,
|
||||
ELFIO::symbol_section_accessor symbol_accessor, ELFIO::string_section_accessor string_accessor)
|
||||
: text(text), read_only(elfio_section_writer(read_only)),
|
||||
: text(text),
|
||||
symbol_accessor(symbol_accessor), string_accessor(string_accessor)
|
||||
{
|
||||
}
|
||||
@ -100,20 +24,6 @@ namespace elna::riscv
|
||||
return text->get_size();
|
||||
}
|
||||
|
||||
std::string_view elfio_writer::sink(const std::byte *data, std::size_t size)
|
||||
{
|
||||
auto offset = read_only.section()->get_size();
|
||||
auto [result, inserted] = read_only(data, size);
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
this->symbol_accessor.add_symbol(this->string_accessor, result.data(), offset,
|
||||
result.size(), ELFIO::STB_LOCAL, ELFIO::STT_NOTYPE, 0,
|
||||
read_only.section()->get_index());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void elfio_writer::sink(const std::string& label)
|
||||
{
|
||||
this->symbol_accessor.add_symbol(this->string_accessor, "printf", 0x00000000, 0,
|
||||
@ -125,6 +35,35 @@ namespace elna::riscv
|
||||
return this->text->get_size();
|
||||
}
|
||||
|
||||
process_writer::process_writer(boost::asio::io_context& context)
|
||||
: pipe(context)
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t process_writer::sink(const std::string& label, const std::byte *data, std::size_t size)
|
||||
{
|
||||
auto network_order_size = boost::endian::native_to_big(static_cast<std::uint16_t>(size));
|
||||
|
||||
auto written = boost::asio::write(this->pipe, boost::asio::buffer(label.data(), label.size() + 1));
|
||||
boost::asio::write(this->pipe, boost::asio::buffer(&network_order_size, 2));
|
||||
boost::asio::write(this->pipe, boost::asio::buffer(data, size));
|
||||
this->text_size += written;
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
void process_writer::sink(const std::string& label)
|
||||
{
|
||||
std::uint16_t data_size{ 0 };
|
||||
boost::asio::write(this->pipe, boost::asio::buffer(label.data(), label.size() + 1));
|
||||
boost::asio::write(this->pipe, boost::asio::buffer(&data_size, 2));
|
||||
}
|
||||
|
||||
std::size_t process_writer::size() const
|
||||
{
|
||||
return this->text_size;
|
||||
}
|
||||
|
||||
std::ptrdiff_t lookup(ELFIO::symbol_section_accessor symbol_accessor, const std::string& label)
|
||||
{
|
||||
for (ptrdiff_t j = 0; j < symbol_accessor.get_symbols_num(); ++j)
|
||||
@ -188,18 +127,21 @@ namespace elna::riscv
|
||||
rel_sec->set_link(sym_sec->get_index());
|
||||
rel_sec->set_flags(ELFIO::SHF_ALLOC);
|
||||
|
||||
// Create read only data section
|
||||
ELFIO::section* ro_sec = writer.sections.add(".rodata");
|
||||
ro_sec->set_type(ELFIO::SHT_PROGBITS);
|
||||
ro_sec->set_flags(ELFIO::SHF_ALLOC);
|
||||
ro_sec->set_addr_align(0x4);
|
||||
|
||||
// Create symbol relocation table writers
|
||||
ELFIO::symbol_section_accessor syma(writer, sym_sec);
|
||||
ELFIO::relocation_section_accessor rela(writer, rel_sec);
|
||||
auto _writer = std::make_shared<elfio_writer>(text_sec, ro_sec, syma, stra);
|
||||
|
||||
auto references = generate(intermediate_code_generator, table, _writer);
|
||||
auto writer1 = std::make_shared<elfio_writer>(text_sec, syma, stra);
|
||||
boost::asio::io_context ctx;
|
||||
auto writer2 = std::make_shared<process_writer>(ctx);
|
||||
boost::process::process child(ctx, "./build/hs/elna", {},
|
||||
boost::process::process_stdio{ { writer2->pipe }, nullptr, nullptr });
|
||||
|
||||
auto references = generate(intermediate_code_generator, table, writer1);
|
||||
generate(intermediate_code_generator, table, writer2);
|
||||
|
||||
writer2->pipe.close();
|
||||
child.wait();
|
||||
|
||||
syma.arrange_local_symbols();
|
||||
|
||||
|
@ -17,6 +17,7 @@ extra-source-files: TODO README
|
||||
common warnings
|
||||
build-depends:
|
||||
base ^>=4.19.1.0,
|
||||
bytestring ^>= 0.12.1,
|
||||
megaparsec ^>= 9.6,
|
||||
text ^>= 2.0
|
||||
ghc-options: -Wall
|
||||
@ -33,7 +34,6 @@ library elna-internal
|
||||
exposed-modules:
|
||||
Language.Elna.Object.Elf
|
||||
build-depends:
|
||||
bytestring ^>= 0.12.1,
|
||||
hashable ^>= 1.4.3,
|
||||
parser-combinators ^>= 1.3,
|
||||
transformers ^>= 0.6.1,
|
||||
@ -45,5 +45,5 @@ executable elna
|
||||
import: warnings
|
||||
main-is: Main.hs
|
||||
build-depends:
|
||||
elna:elna-internal
|
||||
elna:elna-internal
|
||||
hs-source-dirs: src
|
||||
|
@ -2,92 +2,37 @@
|
||||
|
||||
#include "elna/source/parser.hpp"
|
||||
#include "elna/source/optimizer.hpp"
|
||||
#include <boost/asio.hpp>
|
||||
#include <filesystem>
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
namespace elna::riscv
|
||||
{
|
||||
/**
|
||||
* Writer to a single label.
|
||||
*/
|
||||
struct elfio_section_writer
|
||||
{
|
||||
struct entry
|
||||
{
|
||||
std::string_view label;
|
||||
const std::byte *data{ nullptr };
|
||||
std::size_t size{ 0 };
|
||||
};
|
||||
|
||||
/**
|
||||
* An iterator over label and string pairs.
|
||||
*/
|
||||
struct iterator
|
||||
{
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = ptrdiff_t;
|
||||
using value_type = entry;
|
||||
using pointer = const value_type *;
|
||||
using reference = const value_type&;
|
||||
|
||||
reference operator*() const noexcept;
|
||||
pointer operator->() const noexcept;
|
||||
iterator& operator++();
|
||||
iterator& operator++(int);
|
||||
bool operator==(const iterator& that) const;
|
||||
bool operator!=(const iterator& that) const;
|
||||
|
||||
private:
|
||||
std::vector<std::string>::const_iterator labels;
|
||||
std::vector<std::size_t>::const_iterator sizes;
|
||||
value_type payload;
|
||||
|
||||
iterator(std::vector<std::string>::const_iterator labels, std::vector<std::size_t>::const_iterator sizes,
|
||||
const std::byte *data)
|
||||
: labels(labels), sizes(sizes)
|
||||
{
|
||||
if (data != nullptr)
|
||||
{
|
||||
payload = { *this->labels, data, *this->sizes};
|
||||
}
|
||||
}
|
||||
|
||||
iterator(std::vector<std::string>::const_iterator labels, std::vector<std::size_t>::const_iterator sizes)
|
||||
: labels(labels), sizes(sizes), payload{}
|
||||
{
|
||||
}
|
||||
|
||||
friend elfio_section_writer;
|
||||
};
|
||||
explicit elfio_section_writer(ELFIO::section *section);
|
||||
|
||||
void operator()(const std::string& label, const std::byte *data, std::size_t size);
|
||||
std::pair<std::string_view, bool> operator()(const std::byte *data, std::size_t size);
|
||||
|
||||
iterator begin() const;
|
||||
iterator end() const;
|
||||
|
||||
ELFIO::section *section() noexcept;
|
||||
|
||||
private:
|
||||
std::vector<std::string> labels;
|
||||
std::vector<std::size_t> sizes;
|
||||
ELFIO::section *m_section;
|
||||
};
|
||||
|
||||
class elfio_writer final : public source::writer<std::byte>
|
||||
{
|
||||
ELFIO::section *text;
|
||||
elfio_section_writer read_only;
|
||||
ELFIO::symbol_section_accessor symbol_accessor;
|
||||
ELFIO::string_section_accessor string_accessor;
|
||||
|
||||
public:
|
||||
elfio_writer(ELFIO::section *text, ELFIO::section *read_only, ELFIO::symbol_section_accessor symbol_accessor,
|
||||
elfio_writer(ELFIO::section *text, ELFIO::symbol_section_accessor symbol_accessor,
|
||||
ELFIO::string_section_accessor string_accessor);
|
||||
|
||||
std::size_t sink(const std::string& label, const std::byte *data, std::size_t size) override;
|
||||
std::string_view sink(const std::byte *data, std::size_t size) override;
|
||||
void sink(const std::string& label) override;
|
||||
std::size_t size() const override;
|
||||
};
|
||||
|
||||
class process_writer final : public source::writer<std::byte>
|
||||
{
|
||||
std::size_t text_size{ 0 };
|
||||
|
||||
public:
|
||||
boost::asio::writable_pipe pipe;
|
||||
|
||||
process_writer(boost::asio::io_context& context);
|
||||
|
||||
std::size_t sink(const std::string& label, const std::byte *data, std::size_t size) override;
|
||||
void sink(const std::string& label) override;
|
||||
std::size_t size() const override;
|
||||
};
|
||||
|
@ -171,16 +171,6 @@ namespace elna::source
|
||||
*/
|
||||
virtual std::size_t sink(const std::string& label, const T *data, std::size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Writes data and returns a label under that the data can be accessed.
|
||||
*
|
||||
* \param data Data to be written.
|
||||
* \param size Data size.
|
||||
*
|
||||
* \return Label for the symbol.
|
||||
*/
|
||||
virtual std::string_view sink(const T *data, std::size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Creates an external symbol.
|
||||
*/
|
||||
|
44
src/Main.hs
44
src/Main.hs
@ -2,5 +2,47 @@ module Main
|
||||
( main
|
||||
) where
|
||||
|
||||
import Language.Elna.Object.Elf ()
|
||||
import Data.ByteString (ByteString)
|
||||
import qualified Data.ByteString as ByteString
|
||||
import Data.Bits (Bits(..))
|
||||
|
||||
data Chunk
|
||||
= ExternSymbolChunk ByteString
|
||||
| SymbolDefinitionChunk ByteString ByteString
|
||||
deriving Eq
|
||||
|
||||
instance Show Chunk
|
||||
where
|
||||
show (ExternSymbolChunk label)
|
||||
= "ExternExternSymbolChunk "
|
||||
<> show label
|
||||
show (SymbolDefinitionChunk label chunk)
|
||||
= "SymbolDefinitionChunk "
|
||||
<> show label
|
||||
<> "(Size: "
|
||||
<> show (ByteString.length chunk)
|
||||
<> ")"
|
||||
|
||||
splitContents :: [Chunk] -> ByteString -> [Chunk]
|
||||
splitContents accumulator remaining
|
||||
| ByteString.null remaining = accumulator
|
||||
| otherwise =
|
||||
let (label, withoutLabel) = ByteString.drop 1
|
||||
<$> ByteString.break (== 0) remaining
|
||||
(rawSize, chunkAndRest) = ByteString.splitAt 2 withoutLabel
|
||||
in case ByteString.unpack rawSize of
|
||||
[0, 0] -> splitContents (ExternSymbolChunk label : accumulator) chunkAndRest
|
||||
[x, y] ->
|
||||
let chunkSize = shiftL (fromIntegral x) 8 .|. fromIntegral y
|
||||
(chunk, remaining') = ByteString.splitAt chunkSize chunkAndRest
|
||||
in splitContents (SymbolDefinitionChunk label chunk : accumulator) remaining'
|
||||
_ -> ExternSymbolChunk label : accumulator
|
||||
|
||||
main :: IO ()
|
||||
main = putStrLn "Hello, Haskell!"
|
||||
main = do
|
||||
contents <- ByteString.getContents
|
||||
writeFile "here.txt"
|
||||
$ "Total length: " <> show (ByteString.length contents) <> "\n"
|
||||
<> show (splitContents [] contents) <> "\n"
|
||||
putStrLn "Hello, Haskell!"
|
||||
|
Loading…
x
Reference in New Issue
Block a user