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_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
find_package(Boost COMPONENTS program_options REQUIRED)
|
find_package(Boost COMPONENTS process program_options REQUIRED)
|
||||||
find_package(FLEX)
|
find_package(FLEX)
|
||||||
include_directories(${Boost_INCLUDE_DIR})
|
include_directories(${Boost_INCLUDE_DIR})
|
||||||
|
|
||||||
|
@ -1,90 +1,14 @@
|
|||||||
#include "elna/backend/target.hpp"
|
#include "elna/backend/target.hpp"
|
||||||
#include "elna/backend/riscv.hpp"
|
#include "elna/backend/riscv.hpp"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <boost/process/v2.hpp>
|
||||||
|
#include <boost/endian.hpp>
|
||||||
|
|
||||||
namespace elna::riscv
|
namespace elna::riscv
|
||||||
{
|
{
|
||||||
elfio_section_writer::iterator::reference elfio_section_writer::iterator::operator*() const noexcept
|
elfio_writer::elfio_writer(ELFIO::section *text,
|
||||||
{
|
|
||||||
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::symbol_section_accessor symbol_accessor, ELFIO::string_section_accessor string_accessor)
|
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)
|
symbol_accessor(symbol_accessor), string_accessor(string_accessor)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -100,20 +24,6 @@ namespace elna::riscv
|
|||||||
return text->get_size();
|
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)
|
void elfio_writer::sink(const std::string& label)
|
||||||
{
|
{
|
||||||
this->symbol_accessor.add_symbol(this->string_accessor, "printf", 0x00000000, 0,
|
this->symbol_accessor.add_symbol(this->string_accessor, "printf", 0x00000000, 0,
|
||||||
@ -125,6 +35,35 @@ namespace elna::riscv
|
|||||||
return this->text->get_size();
|
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)
|
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)
|
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_link(sym_sec->get_index());
|
||||||
rel_sec->set_flags(ELFIO::SHF_ALLOC);
|
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
|
// Create symbol relocation table writers
|
||||||
ELFIO::symbol_section_accessor syma(writer, sym_sec);
|
ELFIO::symbol_section_accessor syma(writer, sym_sec);
|
||||||
ELFIO::relocation_section_accessor rela(writer, rel_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();
|
syma.arrange_local_symbols();
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ extra-source-files: TODO README
|
|||||||
common warnings
|
common warnings
|
||||||
build-depends:
|
build-depends:
|
||||||
base ^>=4.19.1.0,
|
base ^>=4.19.1.0,
|
||||||
|
bytestring ^>= 0.12.1,
|
||||||
megaparsec ^>= 9.6,
|
megaparsec ^>= 9.6,
|
||||||
text ^>= 2.0
|
text ^>= 2.0
|
||||||
ghc-options: -Wall
|
ghc-options: -Wall
|
||||||
@ -33,7 +34,6 @@ library elna-internal
|
|||||||
exposed-modules:
|
exposed-modules:
|
||||||
Language.Elna.Object.Elf
|
Language.Elna.Object.Elf
|
||||||
build-depends:
|
build-depends:
|
||||||
bytestring ^>= 0.12.1,
|
|
||||||
hashable ^>= 1.4.3,
|
hashable ^>= 1.4.3,
|
||||||
parser-combinators ^>= 1.3,
|
parser-combinators ^>= 1.3,
|
||||||
transformers ^>= 0.6.1,
|
transformers ^>= 0.6.1,
|
||||||
@ -45,5 +45,5 @@ executable elna
|
|||||||
import: warnings
|
import: warnings
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
build-depends:
|
build-depends:
|
||||||
elna:elna-internal
|
elna:elna-internal
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
|
@ -2,92 +2,37 @@
|
|||||||
|
|
||||||
#include "elna/source/parser.hpp"
|
#include "elna/source/parser.hpp"
|
||||||
#include "elna/source/optimizer.hpp"
|
#include "elna/source/optimizer.hpp"
|
||||||
|
#include <boost/asio.hpp>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <elfio/elfio.hpp>
|
#include <elfio/elfio.hpp>
|
||||||
|
|
||||||
namespace elna::riscv
|
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>
|
class elfio_writer final : public source::writer<std::byte>
|
||||||
{
|
{
|
||||||
ELFIO::section *text;
|
ELFIO::section *text;
|
||||||
elfio_section_writer read_only;
|
|
||||||
ELFIO::symbol_section_accessor symbol_accessor;
|
ELFIO::symbol_section_accessor symbol_accessor;
|
||||||
ELFIO::string_section_accessor string_accessor;
|
ELFIO::string_section_accessor string_accessor;
|
||||||
|
|
||||||
public:
|
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);
|
ELFIO::string_section_accessor string_accessor);
|
||||||
|
|
||||||
std::size_t sink(const std::string& label, const std::byte *data, std::size_t size) override;
|
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;
|
void sink(const std::string& label) override;
|
||||||
std::size_t size() const 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;
|
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.
|
* Creates an external symbol.
|
||||||
*/
|
*/
|
||||||
|
44
src/Main.hs
44
src/Main.hs
@ -2,5 +2,47 @@ module Main
|
|||||||
( main
|
( main
|
||||||
) where
|
) 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 :: 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