This commit is contained in:
ouczbs 2024-02-03 22:45:58 +08:00
parent 35968cabd5
commit ec5ce69a80
56 changed files with 842 additions and 1654 deletions

8
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/zlib.iml" filepath="$PROJECT_DIR$/.idea/zlib.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

9
.idea/zlib.iml generated Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1 @@
#include "TestUDRefl.h"

View File

@ -0,0 +1,40 @@
#pragma once
#include <UDRefl/UDRefl.hpp>
#include <iostream>
#include <cmath>
using namespace Ubpa;
using namespace Ubpa::UDRefl;
struct Vec {
float x;
float y;
float norm() const {
return std::sqrt(x * x + y * y);
}
};
int TestUDRefl() {
Mngr.RegisterType<Vec>();
Mngr.AddField<&Vec::x>("x");
Mngr.AddField<&Vec::y>("y");
Mngr.AddMethod<&Vec::norm>("norm");
SharedObject v = Mngr.MakeShared(Type_of<Vec>);
std::cout << v.GetType().GetName() << std::endl; // prints "Vec"
v.Var("x") = 3;
v.Var("y") = 4;
std::cout << "x: " << v.Var("x") << std::endl;
std::cout << "norm: " << v.Invoke("norm") << std::endl;
for (auto&& [name, info] : FieldRange_of<Vec>)
std::cout << name.GetView() << std::endl;
for (auto&& [name, info] : MethodRange_of<Vec>)
std::cout << name.GetView() << std::endl;
for (auto&& [name, var] : v.GetVars())
std::cout << name.GetView() << ": " << var << std::endl;
}

View File

@ -0,0 +1 @@
#include "TestUSRefl.h"

View File

@ -0,0 +1,45 @@
#pragma once
#include "USRefl_99.h"
#include <iostream>
#include <cmath>
#include <functional>
using namespace Ubpa::USRefl;
struct Vec {
float x;
float y;
float norm() const {
return std::sqrt(x * x + y * y);
}
};
template<>
struct Ubpa::USRefl::TypeInfo<Vec> :
TypeInfoBase<Vec>
{
static constexpr AttrList attrs = {};
static constexpr FieldList fields = {
Field {TSTR("x"), &Type::x},
Field {TSTR("y"), &Type::y},
Field {TSTR("norm"), &Type::norm},
};
};
int TestUSRefl() {
TypeInfo<Vec>::fields.ForEach([](const auto& field) {
std::cout << field.name << std::endl;
});
Vec v;
std::invoke(TypeInfo<Vec>::fields.Find(TSTR("x")).value, v) = 3.f;
std::invoke(TypeInfo<Vec>::fields.Find(TSTR("y")).value, v) = 4.f;
std::cout << "x: " << std::invoke(TypeInfo<Vec>::fields.Find(TSTR("x")).value, v) << std::endl;
std::cout << "norm: " << std::invoke(TypeInfo<Vec>::fields.Find(TSTR("norm")).value, v) << std::endl;
TypeInfo<Vec>::ForEachVarOf(v, [](const auto& field, const auto& var) {
std::cout << field.name << ": " << var << std::endl;
});
}

102
src/ReflTest/src/main.cpp Normal file
View File

@ -0,0 +1,102 @@
#include <USRefl/USRefl.h>
#include <iostream>
#include <cassert>
using namespace Ubpa::USRefl;
using namespace std;
template<std::size_t N>
constexpr std::size_t Func() { return N; }
enum class [[enum_attr("enum_attr_value")]] Color {
RED [[enumerator_attr("enumerator_attr_value"), func(&Func<1>)]] = 1,
GREEN [[func(&Func<2>)]] = 2,
BLUE [[func(&Func<3>)]] = 4
};
template<>
struct Ubpa::USRefl::TypeInfo<Color> :
TypeInfoBase<Color>
{
static constexpr AttrList attrs = {
Attr {TSTR("enum_attr"), "enum_attr_value"},
};
static constexpr FieldList fields = {
Field {TSTR("RED"), Type::RED, AttrList {
Attr {TSTR("enumerator_attr"), "enumerator_attr_value"},
Attr {TSTR("func"), &Func<1>},
}},
Field {TSTR("GREEN"), Type::GREEN, AttrList {
Attr {TSTR("func"), &Func<2>},
}},
Field {TSTR("BLUE"), Type::BLUE, AttrList {
Attr {TSTR("func"), &Func<3>},
}},
};
};
int main() {
cout << TypeInfo<Color>::name << endl;
TypeInfo<Color>::fields.ForEach([](auto field) {
cout << field.name << endl;
});
Color red = Color::RED;
std::string_view nameof_red = "RED";
// name -> value
{
// compile-time
static_assert(TypeInfo<Color>::fields.ValueOfName<Color>("GREEN") == Color::GREEN);
// runtime
assert(TypeInfo<Color>::fields.ValueOfName<Color>(nameof_red) == red);
}
// value -> name
{
// compile-time
static_assert(TypeInfo<Color>::fields.NameOfValue(Color::GREEN) == "GREEN");
// runtime
assert(TypeInfo<Color>::fields.NameOfValue(red) == nameof_red);
}
// name -> attr
{
// compile-time
static_assert(TypeInfo<Color>::fields.Find(TSTR("GREEN")).attrs.Find(TSTR("func")).value() == 2);
// runtime
std::size_t rst = static_cast<std::size_t>(-1);
TypeInfo<Color>::fields.FindIf([nameof_red, &rst](auto field) {
if (field.name == nameof_red) {
rst = field.attrs.Find(TSTR("func")).value();
return true;
}
else
return false;
});
assert(rst == 1);
}
// value -> attr
{
static_assert(USRefl_ElemList_GetByValue(TypeInfo<Color>::fields, Color::GREEN).attrs.Find(TSTR("func")).value() == 2);
// runtime
std::size_t rst = static_cast<std::size_t>(-1);
TypeInfo<Color>::fields.FindIf([red, &rst](auto field) {
if (field.value == red) {
rst = field.attrs.Find(TSTR("func")).value();
return true;
}
else
return false;
});
assert(rst == 1);
}
}

View File

@ -1,9 +1,12 @@
add_rules("mode.debug", "mode.release")
target("zasm")
--add_requires("UTemplate","USmallFlat","USRefl","UDRefl")
target("ReflTest")
set_kind("binary")
set_languages("c++20")
add_packages("USRefl","UDRefl")
add_files("src/*.cpp")
add_headerfiles("src/*.h")
--
-- If you want to known more usage about xmake, please see https://xmake.io
--
@ -44,7 +47,7 @@ target("zasm")
-- -- add debug and release modes
-- add_rules("mode.debug", "mode.release")
--
-- -- add macro definition
-- -- add macro defination
-- add_defines("NDEBUG", "_GNU_SOURCE=1")
--
-- -- set warning all as error

View File

@ -1,9 +0,0 @@
//#include <iostream>
//using namespace std;
int main(int argc, char** argv)
{
//cout << "hello world!" << endl;
return 0;
}

View File

@ -20,7 +20,16 @@ public:
public:
LogSystem();
~LogSystem();
static std::shared_ptr<LogSystem> getInstance()
{
static std::weak_ptr<LogSystem> instance;
auto ret = instance.lock();
if (!ret) {
ret.reset(new LogSystem());
instance = ret;
}
return ret;
}
template<typename... TARGS>
void log(LogLevel level, TARGS&&... args)
{
@ -56,4 +65,16 @@ public:
private:
std::shared_ptr<spdlog::logger> m_logger;
};
};
#define LOG_HELPER(LOG_LEVEL, ...) \
LogSystem::getInstance()->log(LOG_LEVEL, "[" + std::string(__FUNCTION__) + "] " + __VA_ARGS__);
#define LOG_DEBUG(...) LOG_HELPER(LogSystem::LogLevel::debug, __VA_ARGS__);
#define LOG_INFO(...) LOG_HELPER(LogSystem::LogLevel::info, __VA_ARGS__);
#define LOG_WARN(...) LOG_HELPER(LogSystem::LogLevel::warn, __VA_ARGS__);
#define LOG_ERROR(...) LOG_HELPER(LogSystem::LogLevel::error, __VA_ARGS__);
#define LOG_FATAL(...) LOG_HELPER(LogSystem::LogLevel::fatal, __VA_ARGS__);

View File

View File

@ -0,0 +1,64 @@
#include <condition_variable>
#include <semaphore>
#include <iostream>
namespace zstd {
template<std::move_constructible T>
class channel {
protected:
int m_tail;
int m_head;
int m_size;
T* m_buf;
std::mutex m_mtx;
std::condition_variable m_cv;
public:
~channel() {
reset();
free(m_buf);
}
channel(int size = 1) {
m_tail = 0;
m_head = 0;
m_size = size;
m_buf = (T*)malloc(sizeof(T) * size);
}
int head() {
return m_head;
}
int tail() {
return m_tail;
}
int count() {
return m_head - m_tail;
}
void reset() {
for (int i = m_tail; i < m_head; i++) {
std::destroy_at(m_buf + (m_tail % m_size));
}
m_tail = 0;
m_head = 0;
}
template<typename... Args>
void release(Args... args) {
std::unique_lock<std::mutex> lck(m_mtx);
if (m_head >= m_tail + m_size) {
std::cout << "release wait \n";
m_cv.wait(lck);
}
std::construct_at(m_buf + m_head % m_size, std::forward<Args>(args)...);
if(m_head++ == m_tail)
m_cv.notify_one();
};
T acquire() {
std::unique_lock<std::mutex> lck(m_mtx);
if (m_tail == m_head) {
std::cout << "acquire wait \n";
m_cv.wait(lck);
}
int tail = m_tail % m_size;
if(m_tail++ == m_head - m_size)
m_cv.notify_one();
return std::move(*(m_buf + tail));
};
};
}

71
src/zcoro/main.cpp Normal file
View File

@ -0,0 +1,71 @@
#include "zthread/channel.h"
#include <iostream>
#include <thread>
#define LOOP_TIMES 10
int del_count = 0;
int add_count = 0;
int cpy_count = 0;
int mov_count = 0;
class object {
public:
const char* name;
int res;
public:
~object() {
char buf[1024];
sprintf(buf, "~~~~ %d %x \n", ++del_count, (int)this);
std::cout << buf;
};
object(const char* name, int res) {
this->name = name;
this->res = res;
char buf[1024];
sprintf(buf, "++++ %d %x \n", ++add_count, (int)this);
std::cout << buf;
}
object(object& obj) {
char buf[1024];
sprintf(buf, "cccc %d %x<--%x\n", ++cpy_count, (int)this, (int) & obj);
std::cout << buf;
this->name = obj.name;
this->res = obj.res;
}
object(object&& obj) noexcept{
char buf[1024];
sprintf(buf, "mmmm %d %x<--%x\n", ++mov_count, (int)this, (int)&obj);
std::cout << buf;
this->name = obj.name;
this->res = obj.res;
}
};
void test1() {
zstd::channel<object> ch(10);
auto p = [&]() {
for (int i = 0; i < LOOP_TIMES * 2; i++) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
ch.release("hello",i);
}
std::cout << "product end " << ch.count() << "\n";
};
auto c = [&](int id) {
for (int i = 0; i < LOOP_TIMES; i++) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
object obj = ch.acquire();
int r = obj.res;
char buf[1024];
sprintf(buf, "recv %d %x head %d - %d\n", r, (int)&obj, ch.head() , ch.tail());
std::cout << buf;
}
std::cout << "consume end " << ch.count() << "\n";
};
std::thread t1(p);
std::thread t2(c, 1);
std::thread t3(c, 2);
t1.join();
t2.join();
t3.join();
std::cout << "test1:: res " << ch.count() << std::endl;
}
int main() {
test1();
}

View File

103
src/zcoro/test/01mutex.cpp Normal file
View File

@ -0,0 +1,103 @@
#include <thread>
#include <mutex>
#include <queue>
#include <iostream>
using namespace std;
#define LOOP_TIMES 100
void test1() {
mutex mtx;
int res = 0;
thread t1([&]() {
for (int i = 0; i < LOOP_TIMES;i++) {
this_thread::sleep_for(chrono::milliseconds(1));
res = res + 1;
}
});
thread t2([&]() {
for (int i = 0; i < LOOP_TIMES; i++) {
this_thread::sleep_for(chrono::milliseconds(1));
mtx.lock();
res = res - 1;
mtx.unlock();
}
});
t1.join();
t2.join();
std::cout << "test1:: res:: " << res << " mutexsize::" << sizeof(mutex) << endl;
}
void test2() {
recursive_mutex mtx;
int res = 0;
thread t1([&]() {
for (int i = 0; i < LOOP_TIMES / 10; i++) {
this_thread::sleep_for(chrono::milliseconds(i));
lock_guard<recursive_mutex> lock(mtx);
res = res + 1;
}
});
thread t2([&]() {
for (int i = 0; i < LOOP_TIMES / 10; i++) {
this_thread::sleep_for(chrono::milliseconds(i));
unique_lock<recursive_mutex> lock(mtx);
res = res - 1;
}
});
t1.join();
t2.join();
std::cout << "test2:: res:: " << res << " lock_guard::" << sizeof(lock_guard<mutex>)
<< " unique_lock::" << sizeof(unique_lock<mutex>) << endl;
}
void test3() {
mutex mtx;
int res = 0;
int error_count = 0;
queue<int> mq;
thread t1([&]() {
for (int i = 0; i < LOOP_TIMES; i++) {
this_thread::sleep_for(chrono::milliseconds(i));
lock_guard<mutex> lock(mtx);
mq.push(i / 2);
res = res + 1;
}
});
thread t2([&]() {
int a = 0;
for (int i = 0; i < LOOP_TIMES;) {
this_thread::sleep_for(chrono::milliseconds(a));
unique_lock<mutex> lock(mtx);
if (mq.empty()) {
error_count++;
continue;
}
i++;
a = mq.front();
mq.pop();
res = res - 1;
}
});
t1.join();
t2.join();
std::cout << "test3:: res:: " << res << " error_count::" << error_count << endl;
}
int main() {
/*
线...
*/
test1();
test2();
/*
mutex
//保证资源的正确使用,如一个厕所只能一个人用
//递归锁可以让前面的人重复上锁,避免函数递归时解锁出错
//排队等待前一个人离开,才能使用
//超时锁,可以先进入自旋,超时后阻塞
*/
test3();
/*
CPU
*/
return 0;
}

View File

@ -0,0 +1,56 @@
#include <iostream>
#include <condition_variable>
#include <thread>
#include <queue>
using namespace std;
#define LOOP_TIMES 50
void test1() {
int res = 0, fake_count = 0;
mutex mtx;
condition_variable cv;
queue<int> mq;
thread t1([&]() {
for (int i = 0; i < LOOP_TIMES * 2; i++) {
this_thread::sleep_for(chrono::milliseconds(i));
//unique_lock<mutex> lock(mtx);
mq.push(i / 4);
//std::cout << "notify one " << i << " " << res << "\n";
cv.notify_all();
res = res + 1;
}
});
auto consume_fn = [&]() {
for (int i = 0; i < LOOP_TIMES; i++) {
this_thread::sleep_for(chrono::milliseconds(i));
unique_lock<mutex> lock(mtx);
while (mq.empty()) {
fake_count++;
//std::cout << "wait one " << i << " " << res << " " << fake_count << "\n";
cv.wait(lock);
}
//std::cout << "handle one " << i << " " << res << "\n";
mq.pop();
}
};
thread t2(consume_fn);
thread t3(consume_fn);
t1.join();
t2.join();
t3.join();
std::cout << "test3:: res:: " << res << " fake_count:: " << fake_count << " condition_variable:: size " << sizeof(cv) << endl;
}
int main() {
test1();
/*
wait(unique_lock<mutex>);
unlock
wait cond 线
lock
notify_one 线
线
*/
return 1;
}

View File

@ -0,0 +1,66 @@
#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <semaphore>
using namespace std;
#define LOOP_TIMES 1000
void test1() {
int res = 0;
binary_semaphore bs(0);
thread t1([&]() {
this_thread::sleep_for(chrono::milliseconds(1000));
res = 12;
bs.release();
});
t1.detach();
bs.acquire();
std::cout << "test1:: res "<< res << endl;
}
void test2() {
int res = 0;
counting_semaphore<> cs(0);
queue<int> mq;
mutex mtx;
auto p = [&]() {
for (int i = 0; i < LOOP_TIMES * 2; i++) {
{ //保证res 与 mq 的修改线程安全
lock_guard<mutex> lock(mtx);
mq.push(i / 2);
res = res + 1;
}
cs.release();
}
std::cout << "product end " << res << "\n";
};
auto c = [&](int id) {
for (int i = 0; i < LOOP_TIMES; i++) {
cs.acquire();//这里不存在虚假唤醒,一定能抢到资源,只是资源顺序不确定
{
lock_guard<mutex> lock(mtx);
mq.pop();
res = res - 1;
}
}
std::cout << "consume end " << id << " -> " << res << "\n";
};
thread t1(p);
thread t2(c, 1);
thread t3(c, 2);
t1.join();
t2.join();
t3.join();
std::cout << "test1:: res " << res << " mq " << mq.size() << endl;
}
int main() {
test1();
test2();
//信号量可以实现一批资源的分配
//信号量可由条件变量与锁实现
//信号量封装后可以实现chanel效果
std::cout << "binary_semaphore size:: " << sizeof(binary_semaphore) <<
" counting_semaphore<3> size:: " << sizeof(counting_semaphore<3>)<<
" counting_semaphore<10> size:: " << sizeof(counting_semaphore<10>) << endl;
return 1;
}

View File

@ -0,0 +1,50 @@
#include <iostream>
#include <thread>
#include <future>
using namespace std;
void test1() {
promise<int> p;
future<int> f = p.get_future();
thread t1([&]() {
this_thread::sleep_for(chrono::milliseconds(1000));
p.set_value(12);
this_thread::sleep_for(chrono::milliseconds(1000));
});
t1.detach();
std::cout << "test1:: res:: " << f.get() << endl;
}
void test2() {
promise<int> p;
future<int> f = p.get_future();
shared_future<int> sf = f.share();
thread t1([&]() {
this_thread::sleep_for(chrono::milliseconds(1000));
p.set_value(12);
this_thread::sleep_for(chrono::milliseconds(1000));
});
t1.detach();
std::cout << "test2:: res:: " << sf.get() << sf .get() << endl;
}
void test3() {
auto fn = []()->int {
this_thread::sleep_for(chrono::milliseconds(1000));
return 12;
};
auto f = async(launch::async, fn);
packaged_task<int()> t(fn);
t();
std::cout << "test3:: res:: " << f.get() << t.get_future().get() << endl;
}
int main() {
test1();
test2();
test3();
//这里通过条件变量 | 信号量 + 共享变量就能实现
//用promise-future 感觉很浪费
std::cout << "promise size:: " << sizeof(promise<int>) <<
" future size:: " << sizeof(future<int>) <<
" shared_future size:: " << sizeof(shared_future<int>) << endl;
return 1;
}

29
src/zcoro/xmake.lua Normal file
View File

@ -0,0 +1,29 @@
set_languages("cxx20")
target("zcoro")
set_kind("static")
add_includedirs("include", {public = true})
add_files("src/**/*.cpp")
add_headerfiles("include/**/*.h")
target("zcoro_test")
set_kind("binary")
add_deps("zcoro")
add_files("main.cpp")
-- target("zcoro_test01_mutex")
-- set_kind("binary")
-- add_deps("zcoro")
-- add_files("test/01mutex.cpp")
-- target("zcoro_test02_condition")
-- set_kind("binary")
-- add_deps("zcoro")
-- add_files("test/02condition.cpp")
-- target("zcoro_test03_semaphore")
-- set_kind("binary")
-- add_deps("zcoro")
-- add_files("test/03semaphore.cpp")
-- target("zcoro_test04_promise")
-- set_kind("binary")
-- add_deps("zcoro")
-- add_files("test/04promise.cpp")

38
src/zelf/.gitignore vendored
View File

@ -1,38 +0,0 @@
# kdiff3 ignore
*.orig
# maven ignore
target/
# eclipse ignore
.settings/
.project
.classpath
# idea ignore
.idea/
*.ipr
*.iml
*.txt
*.iws
# temp ignore
*.log
*.cache
*.diff
*.patch
*.tmp
# system ignore
.DS_Store
Thumbs.db
# package ignore (optional)
# *.jar
# *.war
# *.zip
# *.tar
# *.tar.gz
# linux
.directory

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 458 KiB

Binary file not shown.

View File

@ -1,17 +0,0 @@
// ElfFileParser.cpp : Defines the entry point for the application.
//
#include <iostream>
#include "ElfParser.h"
using namespace std;
int main()
{
cout << "开始解析:" << endl;
ElfParser elf_parser(R"(file/main.cpp.obj)");
// ElfParser elf_parser(R"(..\..\..\file\arm64-v8a\libfoo.so)");
elf_parser.parse();
cout << "\n解析完毕!" << endl;
return 0;
}

View File

@ -1,793 +0,0 @@
#include "ElfParser.h"
#include <cstring>
#include <vector>
#include "type/elf.h"
#include "util/Printer.h"
ElfParser::ElfParser() : ElfParser(nullptr) {}
ElfParser::ElfParser(char const* elf_file)
{
this->elf_file_ = nullptr;
this->elf_bit_ = 0;
this->elf_header32_ = Elf32_Ehdr();
this->elf_header64_ = Elf64_Ehdr();
this->program_header32_list_ = nullptr;
this->program_header64_list_ = nullptr;
this->section_header32_list_ = nullptr;
this->section_header64_list_ = nullptr;
this->symbol32_list_ = nullptr;
this->symbol64_list_ = nullptr;
this->string_table_ = nullptr;
this->symbol_string_table_ = nullptr;
this->relocation32_list_ = nullptr;
this->relocation64_list_ = nullptr;
if (elf_file == nullptr)
return;
// const auto f = fopen_s(&this->elf_file_, elf_file, "rb");
this->elf_file_ = fopen(elf_file, "rb");
printf("构造函数open elf file: %s\n\n", elf_file);
if (this->elf_file_ == nullptr)
printf("构造函数open elf file error: %s\n", elf_file);
}
ElfParser::~ElfParser()
{
printf("\n>>>>>>>>>>>> release <<<<<<<<<<<<\n\n");
if (this->elf_file_ != nullptr) {
printf("close elf file.\n");
fclose(this->elf_file_);
}
if (this->section_header32_list_ != nullptr)
{
printf("delete section header 32 array.\n");
delete[] this->section_header32_list_;
this->section_header32_list_ = nullptr;
}
if (this->section_header64_list_ != nullptr)
{
printf("delete section header 64 array.\n");
delete[] this->section_header64_list_;
this->section_header64_list_ = nullptr;
}
if (this->program_header32_list_ != nullptr)
{
printf("delete program header 32 array.\n");
delete[] this->program_header32_list_;
this->program_header32_list_ = nullptr;
}
if (this->program_header64_list_ != nullptr)
{
printf("delete program header 64 array.\n");
delete[] this->program_header64_list_;
this->program_header64_list_ = nullptr;
}
if (this->string_table_ != nullptr)
{
printf("delete string table.\n");
delete[] this->string_table_;
this->string_table_ = nullptr;
}
if (this->symbol_string_table_ != nullptr)
{
printf("delete symbol string table.\n");
delete[] this->symbol_string_table_;
this->symbol_string_table_ = nullptr;
}
if (this->symbol32_list_ != nullptr)
{
printf("delete symbol 32 list.\n");
delete[] this->symbol32_list_;
this->symbol32_list_ = nullptr;
}
if (this->symbol64_list_ != nullptr)
{
printf("delete symbol 64 list.\n");
delete[] this->symbol64_list_;
this->symbol64_list_ = nullptr;
}
if (this->relocation32_list_ != nullptr)
{
printf("delete relocation 32 list.\n");
delete[] this->relocation32_list_;
this->relocation32_list_ = nullptr;
}
if (this->relocation64_list_ != nullptr)
{
printf("delete relocation 64 list.\n");
delete[] this->relocation64_list_;
this->relocation64_list_ = nullptr;
}
}
void ElfParser::parse()
{
printf(">>>>>>>>>>>> parse elf header <<<<<<<<<<<<\n\n");
uint8_t bit;
if (!check_elf()) {
printf("it is not a elf file.\n");
return;
}
parse_elf_header();
parse_section_header_list();
parse_string_table();
print_section_header_list();
parse_symbol_string_table();
parse_program_header_list();
parse_section_list();
}
template <typename T = Elf32_Ehdr>
void print_elf_header(T* header, const uint8_t bit)
{
printf("ident: \t\t");
Printer::print_char_array(header->e_ident, 16);
printf("type: \t\t%u\n", header->e_type);
printf("machine: \t%u\n", header->e_machine);
printf("version: \t%u\n", header->e_version);
if (bit == 32)
{
printf("entry: \t\t%u\n", header->e_entry);
printf("phoff: \t\t%u\n", header->e_phoff);
printf("shoff: \t\t%u\n", header->e_shoff);
}
else // bit == 64
{
printf("entry: \t\t%llu\n", header->e_entry);
printf("phoff: \t\t%llu\n", header->e_phoff);
printf("shoff: \t\t%llu\n", header->e_shoff);
}
printf("flags: \t\t0x%x\n", header->e_flags);
printf("ehsize: \t%u\n", header->e_ehsize);
printf("phentsize: \t%u\n", header->e_phentsize);
printf("phnum: \t\t%u\n", header->e_phnum);
printf("shentsize: \t%u\n", header->e_shentsize);
printf("shnum: \t\t%u\n", header->e_shnum);
printf("shstrndx: \t%u\n", header->e_shstrndx);
}
bool ElfParser::check_elf()
{
unsigned char elf_ident[16] = { 0 };
if (0 == fread(elf_ident, sizeof(char), 16, this->elf_file_))
{
printf("check elf error: read error");
return false;
}
if (memcmp(elf_ident, ElfMagic, strlen(ElfMagic)) != 0)
return false;
char elf_type[10] = "ERROR";
switch (elf_ident[4])
{
case ELFCLASSNONE:
strcpy(elf_type, "invalid");
break;
case ELFCLASS32:
strcpy(elf_type, "ELF32");
this->elf_bit_ = 32;
break;
case ELFCLASS64:
strcpy(elf_type, "ELF64");
this->elf_bit_ = 64;
break;
default:
break;
}
printf("Class: \t\t%s\n", elf_type);
char elf_order[15] = "ERROR";
switch (elf_ident[5])
{
case ELFDATANONE:
strcpy(elf_order, "invalid");
break;
case ELFDATA2LSB:
strcpy(elf_order, "little endian");
break;
case ELFDATA2MSB:
strcpy(elf_order, "big endian");
break;
default:
break;
}
printf("Order: \t\t%s\n", elf_order);
return true;
}
void ElfParser::parse_elf_header()
{
if (0 != fseek(this->elf_file_, 0, 0))
{
printf("#parse_elf_header - seek file error.\n");
return;
}
void* elf_header = nullptr;
size_t elf_header_size = 0;
if (this->elf_bit_ == 32)
{
elf_header = &this->elf_header32_;
elf_header_size = sizeof(Elf32_Ehdr);
}
else // this->elf_bit_ == 64
{
elf_header = &this->elf_header64_;
elf_header_size = sizeof(Elf64_Ehdr);
}
if (0 == fread(elf_header, elf_header_size, 1, this->elf_file_))
{
printf("parse elf header%d error.\n", this->elf_bit_);
return;
}
if (this->elf_bit_ == 32)
print_elf_header(&this->elf_header32_, 32);
else // this->elf_bit_ == 64
print_elf_header(&this->elf_header64_, 64);
}
// todo: pretty print
template <typename T = Elf32_Shdr>
static void print_section_header(T* header, const uint8_t bit)
{
#ifdef _PRINT_SECTION_HEADER_LIST_
printf("sh_name: \t%u\n", header->sh_name);
printf("sh_type: \t0x%x\n", header->sh_type);
printf("sh_link: \t%u\n", header->sh_link);
printf("sh_info: \t%u\n", header->sh_info);
if (bit == 32)
{
printf("sh_flags: \t%u\n", header->sh_flags);
printf("sh_offset: \t%u\n", header->sh_offset);
printf("sh_size: \t%u\n", header->sh_size);
printf("sh_addr: \t%u\n", header->sh_addr);
printf("sh_addralign: \t%u\n", header->sh_addralign);
printf("sh_entsize: \t%u\n", header->sh_entsize);
}
else // bit == 64
{
printf("sh_flags: \t%llu\n", header->sh_flags);
printf("sh_offset: \t%llu\n", header->sh_offset);
printf("sh_size: \t%llu\n", header->sh_size);
printf("sh_addr: \t%llu\n", header->sh_addr);
printf("sh_addralign: \t%llu\n", header->sh_addralign);
printf("sh_entsize: %llu\n", header->sh_entsize);
}
#endif // _PRINT_PROGRAM_HEADER_LIST_
}
void ElfParser::parse_section_header_list()
{
printf("\n>>>>>>>>>>>> parse section header list <<<<<<<<<<<<\n\n");
long section_header_offset = 0;
size_t section_header_count = 0;
size_t section_header_size = 0;
void* section_header_list = nullptr;
if (this->elf_bit_ == 32)
{
section_header_offset = this->elf_header32_.e_shoff;
section_header_count = this->elf_header32_.e_shnum;
section_header_size = sizeof(Elf32_Shdr);
this->section_header32_list_ = new Elf32_Shdr[section_header_count];
section_header_list = this->section_header32_list_;
printf("section header offset: \t%u\n", this->elf_header32_.e_shoff);
printf("section header size: \t%u\n", this->elf_header32_.e_shnum);
}
else // this->elf_bit_ == 64
{
section_header_offset = this->elf_header64_.e_shoff;
section_header_count = this->elf_header64_.e_shnum;
section_header_size = sizeof(Elf64_Shdr);
this->section_header64_list_ = new Elf64_Shdr[section_header_count];
section_header_list = this->section_header64_list_;
printf("section header offset: \t%llu\n", this->elf_header64_.e_shoff);
printf("section header size: \t%u\n", this->elf_header64_.e_shnum);
}
if (0 != fseek(this->elf_file_, section_header_offset, 0))
{
printf("#parse_section_header - seek file error.\n");
return;
}
if (0 == fread(section_header_list, section_header_size, section_header_count, this->elf_file_))
{
printf("parse section header%d error.\n", this->elf_bit_);
return;
}
}
void ElfParser::parse_string_table()
{
printf("\n>>>>>>>>>>>> parse string table <<<<<<<<<<<<\n\n");
// for .shstrtab;
size_t offset;
size_t size;
if (this->elf_bit_ == 32)
{
// 字符串表下标
const auto str_table_index = this->elf_header32_.e_shstrndx;
const auto& section_header = this->section_header32_list_[str_table_index];
offset = section_header.sh_offset;
size = section_header.sh_size;
}
else // this->elf_bit_ == 64
{
const auto str_table_index = this->elf_header64_.e_shstrndx;
const auto& section_header = this->section_header64_list_[str_table_index];
offset = section_header.sh_offset;
size = section_header.sh_size;
}
if (0 != fseek(this->elf_file_, offset, 0))
{
printf("#parse_string_table - seek file error.\n");
return;
}
this->string_table_ = new char[size];
if (0 == fread(this->string_table_, size, 1, this->elf_file_))
{
printf("parse string table%d error.\n", this->elf_bit_);
return;
}
size_t string_count = 0;
for (size_t i = 0; i < size; i++)
{
if (this->string_table_[i] == 0 && i != (size - 1))
{
const auto off = i + 1;
const auto* str = get_string_from_string_table(off);
const auto len = strlen(str);
printf("str[%llu] \tlen: %llu, s: %s\n", off, len, str);
string_count++;
}
}
printf("string count: %llu\n", string_count);
}
void ElfParser::print_section_header_list() const
{
#ifdef _PRINT_SECTION_HEADER_LIST_
size_t section_header_count = 0;
if (this->elf_bit_ == 32)
section_header_count = this->elf_header32_.e_shnum;
else // this->elf_bit_ == 64
section_header_count = this->elf_header64_.e_shnum;
for (size_t i = 0; i < section_header_count; i++)
{
printf("\n>>>>>>>>>>>> parse section header <<<<<<<<<<<<\n\n");
printf("index: \t\t%llu\n", i);
if (this->elf_bit_ == 32)
{
printf("name: \t\t%s\n\n", get_string_from_string_table(this->section_header32_list_[i].sh_name));
print_section_header(&this->section_header32_list_[i], this->elf_bit_);
}
else // this->elf_bit_ == 64
{
printf("name: \t\t%s\n\n", get_string_from_string_table(this->section_header64_list_[i].sh_name));
print_section_header(&this->section_header64_list_[i], this->elf_bit_);
}
}
#endif // _PRINT_SECTION_HEADER_LIST_
}
void ElfParser::parse_symbol_string_table()
{
printf("\n>>>>>>>>>>>> parse symbol string table <<<<<<<<<<<<\n\n");
// for .dynstr
size_t offset = 0;
size_t size = 0;
if(this->elf_bit_ == 32)
{
for (size_t i = 0; i < this->elf_header32_.e_shnum; i++)
{
auto& section_header = this->section_header32_list_[i];
const auto* section_name = get_string_from_string_table(section_header.sh_name);
if(section_header.sh_type == SHT_STRTAB && strcmp(section_name, ".dynstr") == 0)
{
offset = section_header.sh_offset;
size = section_header.sh_size;
break;
}
}
}
else // this->elf_bit_ == 32
{
for (size_t i = 0; i < this->elf_header64_.e_shnum; i++)
{
auto& section_header = this->section_header64_list_[i];
const auto* section_name = get_string_from_string_table(section_header.sh_name);
if (section_header.sh_type == SHT_STRTAB && strcmp(section_name, ".dynstr") == 0)
{
offset = section_header.sh_offset;
size = section_header.sh_size;
break;
}
}
}
if(offset == 0 || size == 0)
{
printf("error: not found section .dynstr\n");
return;
}
if (0 != fseek(this->elf_file_, offset, 0))
{
printf("#parse_symbol_string_table - seek file error.\n");
return;
}
this->symbol_string_table_ = new char[size];
if (0 == fread(this->symbol_string_table_, size, 1, this->elf_file_))
{
printf("parse symbol string table%d error.\n", this->elf_bit_);
return;
}
size_t string_count = 0;
for (size_t i = 0; i < size; i++)
{
if (this->symbol_string_table_[i] == 0 && i != (size - 1))
{
const auto off = i + 1;
const auto* str = get_string_from_symbol_string_table(off);
const auto len = strlen(str);
printf("str[%llu] \tlen: %llu, s: %s\n", off, len, str);
string_count++;
}
}
printf("string count: %llu\n", string_count);
}
const char* ElfParser::get_string_from_string_table(const size_t offset) const
{
return &this->string_table_[offset];
}
inline const char* ElfParser::get_string_from_symbol_string_table(size_t offset) const
{
return &this->symbol_string_table_[offset];
}
// todo: pretty print
template <typename T = Elf32_Phdr>
static void print_program_header(T* header, const uint8_t bit)
{
#ifdef _PRINT_PROGRAM_HEADER_LIST_
printf("p_type: \t0x%x\n", header->p_type);
printf("p_flags: \t%u\n", header->p_flags);
if (bit == 32)
{
printf("p_offset: \t%u\n", header->p_offset);
printf("p_vaddr: \t%u\n", header->p_vaddr);
printf("p_paddr: \t%u\n", header->p_paddr);
printf("p_filesz: \t%u\n", header->p_filesz);
printf("p_memsz: \t%u\n", header->p_memsz);
printf("p_align: \t%u\n", header->p_align);
}
else // bit == 64
{
printf("p_offset: \t0x%x\n", header->p_offset);
printf("p_vaddr: \t%llu\n", header->p_vaddr);
printf("p_paddr: \t%llu\n", header->p_paddr);
printf("p_filesz: \t%llu\n", header->p_filesz);
printf("p_memsz: \t%llu\n", header->p_memsz);
printf("p_align: \t%llu\n", header->p_align);
}
#endif // _PRINT_PROGRAM_HEADER_LIST_
}
void ElfParser::parse_program_header_list()
{
printf("\n>>>>>>>>>>>> parse program list <<<<<<<<<<<<\n\n");
long program_header_list_offset = 0;
size_t program_header_count = 0;
size_t program_header_size = 0;
void* program_header_list = nullptr;
if (this->elf_bit_ == 32)
{
program_header_list_offset = this->elf_header32_.e_phoff;
program_header_count = this->elf_header32_.e_phnum;
program_header_size = sizeof(Elf32_Phdr);
this->program_header32_list_ = new Elf32_Phdr[program_header_count];
program_header_list = this->program_header32_list_;
printf("program header offset: \t%u\n", this->elf_header32_.e_phoff);
printf("program header size: \t%u\n", this->elf_header32_.e_phnum);
}
else // this->elf_bit_ == 64
{
program_header_list_offset = this->elf_header64_.e_phoff;
program_header_count = this->elf_header64_.e_phnum;
program_header_size = sizeof(Elf64_Phdr);
this->program_header64_list_ = new Elf64_Phdr[program_header_count];
program_header_list = this->program_header64_list_;
printf("program header offset: \t%llu\n", this->elf_header64_.e_phoff);
printf("program header size: \t%u\n", this->elf_header64_.e_phnum);
}
if (0 != fseek(this->elf_file_, program_header_list_offset, 0))
{
printf("#parse_program_header_list - seek file error.\n");
return;
}
if (0 == fread(program_header_list, program_header_size, program_header_count, this->elf_file_))
{
printf("parse program header%d error.\n", this->elf_bit_);
return;
}
#ifdef _PRINT_PROGRAM_HEADER_LIST_
for (size_t i = 0; i < program_header_count; i++)
{
printf("\n>>>>>>>>>>>> parse program header <<<<<<<<<<<<\n\n");
printf("index: \t\t%llu\n\n", i);
if (this->elf_bit_ == 32)
print_program_header(&this->program_header32_list_[i], this->elf_bit_);
else // this->elf_bit_ == 64
print_program_header(&this->program_header64_list_[i], this->elf_bit_);
}
#endif // _PRINT_PROGRAM_HEADER_LIST_
}
void ElfParser::parse_section_list()
{
printf("\n>>>>>>>>>>>> parse section list <<<<<<<<<<<<\n\n");
size_t list_len = 0;
if (this->elf_bit_ == 32)
list_len = this->elf_header32_.e_shnum;
else // this->elf_bit_ == 64
list_len = this->elf_header64_.e_shnum;
if (this->elf_bit_ == 32)
{
for (size_t i = 0; i < list_len; i++)
{
auto& section_header = this->section_header32_list_[i];
printf("parse section: %s\n", get_string_from_string_table(section_header.sh_name));
switch (section_header.sh_type)
{
case SHT_SYMTAB:
break;
case SHT_DYNSYM:
parse_symbol_table(section_header.sh_offset, section_header.sh_size);
break;
case SHT_REL:
parse_relocation_table(section_header.sh_offset, section_header.sh_size);
break;
default:
printf("ignored.\n");
break;
}
}
}
else // this->elf_bit_ == 64
{
for (size_t i = 0; i < list_len; i++)
{
auto& section_header = this->section_header64_list_[i];
printf("parse section: %s\n", get_string_from_string_table(section_header.sh_name));
switch (section_header.sh_type)
{
case SHT_SYMTAB:
break;
case SHT_DYNSYM:
parse_symbol_table(section_header.sh_offset, section_header.sh_size);
break;
default:
printf("ignored.\n");
break;
}
}
}
}
template <typename T = Elf32_Sym>
static void print_symbol(T* symbol, const uint8_t bit)
{
if (bit == 32)
{
printf("st_name: \t%u\n", symbol->st_name);
printf("st_value: \t%u\n", symbol->st_value);
printf("st_size: \t%u\n", symbol->st_size);
printf("st_info: \t%u\n", symbol->st_info);
printf("st_other: \t%u\n", symbol->st_other);
printf("st_shndx: \t%u\n", symbol->st_shndx);
}
else // bit == 64
{
printf("st_name: \t%llu\n", symbol->st_name);
printf("st_value: \t%llu\n", symbol->st_value);
printf("st_size: \t%llu\n", symbol->st_size);
printf("st_info: \t%llu\n", symbol->st_info);
printf("st_other: \t%llu\n", symbol->st_other);
printf("st_shndx: \t%llu\n", symbol->st_shndx);
}
}
void ElfParser::parse_symbol_table(const long offset, const size_t size)
{
printf("\n>>>>>>>>>>>> parse symbol table <<<<<<<<<<<<\n\n");
if (0 != fseek(this->elf_file_, offset, 0))
{
printf("#parse_symbol_table - seek file error.\n");
return;
}
size_t sym_size = 0;
size_t sym_count = 0;
void* symbol_buffer = nullptr;
if (this->elf_bit_ == 32)
{
sym_size = sizeof(Elf32_Sym);
sym_count = size / sym_size;
this->symbol32_list_ = new Elf32_Sym[sym_count];
symbol_buffer = this->symbol32_list_;
}
else // this->elf_bit_ == 64
{
sym_size = sizeof(Elf64_Sym);
sym_count = size / sym_size;
this->symbol64_list_ = new Elf64_Sym[sym_count];
symbol_buffer = this->symbol64_list_;
}
printf("symbol count: %llu\n", sym_count);
if (0 == fread(symbol_buffer, sym_size, sym_count, this->elf_file_))
{
printf("parse symbol table%d error.\n", this->elf_bit_);
return;
}
#ifdef _PRINT_SYMBOL_TABLE_
for (size_t i = 0; i < sym_count; i++)
{
printf("\n>>>>>>>>>>>> parse symbol <<<<<<<<<<<<\n\n");
printf("index: %llu\n", i);
if (this->elf_bit_ == 32)
{
auto& symbol = this->symbol32_list_[i];
printf("symbol name: %s\n\n", get_string_from_symbol_string_table(symbol.st_name));
print_symbol(&symbol, this->elf_bit_);
}
else // this-elf_bit_ == 64
{
auto& symbol = this->symbol64_list_[i];
printf("symbol name: %s\n\n", get_string_from_symbol_string_table(symbol.st_name));
print_symbol(&symbol, this->elf_bit_);
}
}
#endif // _PRINT_SYMBOL_TABLE_
}
void ElfParser::parse_relocation_table(const long offset, const size_t size)
{
printf("\n>>>>>>>>>>>> parse relocation table <<<<<<<<<<<<\n\n");
if (0 != fseek(this->elf_file_, offset, 0))
{
printf("#parse_relocation_table - seek file error.\n");
return;
}
size_t rel_size = 0;
size_t rel_count = 0;
void* rel_buffer = nullptr;
if (this->elf_bit_ == 32)
{
rel_size = sizeof(Elf32_Rel);
rel_count = size / rel_size;
this->relocation32_list_ = new Elf32_Rel[rel_count];
rel_buffer = this->relocation32_list_;
}
else // this->elf_bit_ == 64
{
rel_size = sizeof(Elf64_Rel);
rel_count = size / rel_size;
this->relocation64_list_ = new Elf64_Rel[rel_count];
rel_buffer = this->relocation64_list_;
}
printf("relocation entries count: %llu\n", rel_count);
if (0 == fread(rel_buffer, rel_size, rel_count, this->elf_file_))
{
printf("parse relocation table%d error.\n", this->elf_bit_);
return;
}
#ifdef _PRINT_RELOCATION_TABLE
for (size_t i = 0; i < rel_count; i++)
{
printf("\n>>>>>>>>>>>> parse relocation entry <<<<<<<<<<<<\n\n");
printf("index: %llu\n\n", i);
if (this->elf_bit_ == 32)
{
auto& relocation = this->relocation32_list_[i];
printf("r_offset: \t%u\n", relocation.r_offset);
printf("r_info: \t%u\n", relocation.r_info);
}
else // this-elf_bit_ == 64
{
auto& relocation = this->relocation64_list_[i];
printf("r_offset: \t%llu\n", relocation.r_offset);
printf("r_info: \t%llu\n", relocation.r_info);
}
}
#endif // _PRINT_RELOCATION_TABLE
}

View File

@ -1,50 +0,0 @@
#ifndef ELF_PARSER_H
#define ELF_PARSER_H
#include <cstdio>
#include "type/elf.h"
class ElfParser
{
public:
ElfParser();
explicit ElfParser(char const* elf_file);
~ElfParser();
void parse();
private:
FILE* elf_file_;
uint8_t elf_bit_;
Elf32_Ehdr elf_header32_{};
Elf64_Ehdr elf_header64_{};
Elf32_Phdr* program_header32_list_;
Elf64_Phdr* program_header64_list_;
Elf32_Shdr* section_header32_list_;
Elf64_Shdr* section_header64_list_;
char* string_table_;
char* symbol_string_table_;
Elf32_Sym* symbol32_list_;
Elf64_Sym* symbol64_list_;
Elf32_Rel* relocation32_list_;
Elf64_Rel* relocation64_list_;
bool check_elf();
void parse_elf_header();
void parse_section_header_list();
void parse_string_table();
void print_section_header_list() const;
void parse_symbol_string_table();
void parse_program_header_list();
void parse_section_list();
void parse_symbol_table(long offset, size_t size);
void parse_relocation_table(long offset, size_t size);
const char* get_string_from_string_table(size_t offset) const;
const char* get_string_from_symbol_string_table(size_t offset) const;
};
#endif // ELF_PARSER_H

View File

@ -1,549 +0,0 @@
#ifndef ELF_H
#define ELF_H
#include <cstdint>
typedef uint32_t Elf32_Addr; // Program address
typedef uint32_t Elf32_Off; // File offset
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Word;
typedef int32_t Elf32_Sword;
typedef uint64_t Elf64_Addr;
typedef uint64_t Elf64_Off;
typedef uint16_t Elf64_Half;
typedef uint32_t Elf64_Word;
typedef int32_t Elf64_Sword;
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
static constexpr char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
// e_ident size and indices.
enum {
EI_MAG0 = 0, // 文件标识索引
EI_MAG1 = 1, // 文件标识索引
EI_MAG2 = 2, // 文件标识索引
EI_MAG3 = 3, // 文件标识索引
EI_CLASS = 4, // File class.
EI_DATA = 5, // Data encoding.
EI_VERSION = 6, // File version.
EI_OSABI = 7, // OS/ABI identification.
EI_ABIVERSION = 8, // ABI version.
EI_PAD = 9, // Start of padding bytes.
EI_NIDENT = 16 // Number of bytes in e_ident.
};
constexpr char ELFMAG0 = ElfMagic[EI_MAG0];
constexpr char ELFMAG1 = ElfMagic[EI_MAG1];
constexpr char ELFMAG2 = ElfMagic[EI_MAG2];
constexpr char ELFMAG3 = ElfMagic[EI_MAG3];
constexpr char ELFMAG[] = "\177ELF";
constexpr int SELFMAG = 4;
constexpr int NT_PRSTATUS = 1;
// Elf 文件头
struct Elf32_Ehdr {
unsigned char e_ident[EI_NIDENT]; // 文件标识
Elf32_Half e_type; // 文件类型
Elf32_Half e_machine; // ELF 文件的 CPU 平台属性,相关常量以 EM_ 开头
Elf32_Word e_version; // ELF 版本号,一般为常数 1
Elf32_Addr e_entry; // 入口地址,规定 ELF 程序的入口虚拟地址,操作系统在加载完该程序后从这个地址开始执行进程的指令
Elf32_Off e_phoff; // Program header 表的文件偏移字节
Elf32_Off e_shoff; // 段表在文件中的偏移
Elf32_Word e_flags; // LF 标志位,用来标识一些 ELF 文件平台相关的属性。相关常量格式一般为 EF_machine_flagmachine 为平台flag 为标志
Elf32_Half e_ehsize; // ELF 文件头本身的大小
Elf32_Half e_phentsize; // Program header 表的大小
Elf32_Half e_phnum; // Program header 表的数量
Elf32_Half e_shentsize; // 段表描述符的大小,这个一般等于一节
Elf32_Half e_shnum; // 段表描述符数量。这个值等于 ELF 文件中拥有段的数量
Elf32_Half e_shstrndx; // 段表字符串表所在的段在段表中的下标
};
struct Elf64_Ehdr {
unsigned char e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
};
// 程序头表,表示装载后的 Segment 结构
struct Elf32_Phdr {
Elf32_Word p_type; // 段类型
Elf32_Off p_offset; // 段在文件中的偏移
Elf32_Addr p_vaddr; // 段的第一个字节在虚拟地址空间的起始位置,整个程序表头中
Elf32_Addr p_paddr; // 段的物理装载地址,即 LMALoad Memory Address一般情况下 p_paddr 和 p_vaddr 是相同的
Elf32_Word p_filesz; // 段在 ELF 文件中所占空间的长度,可能为 0
Elf32_Word p_memsz; // 段在进程虚拟空间中所占空间的长度,可能为 0
Elf32_Word p_flags; // 段的权限属性,比如可读 "R",可写 "W" 和可执行 "X"
Elf32_Word p_align; // 段的对齐属性,实际对齐字节等于 2 的 p_align 次方
};
struct Elf64_Phdr {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
};
// File types
enum {
ET_NONE = 0, // No file type
ET_REL = 1, // Relocatable file
ET_EXEC = 2, // Executable file
ET_DYN = 3, // Shared object file
ET_CORE = 4, // Core file
ET_LOPROC = 0xff00, // Beginning of processor-specific codes
ET_HIPROC = 0xffff // Processor-specific
};
// Versioning
enum {
EV_NONE = 0,
EV_CURRENT = 1
};
// Machine architectures
enum {
EM_NONE = 0, // No machine
EM_M32 = 1, // AT&T WE 32100
EM_SPARC = 2, // SPARC
EM_386 = 3, // Intel 386
EM_68K = 4, // Motorola 68000
EM_88K = 5, // Motorola 88000
EM_486 = 6, // Intel 486 (deprecated)
EM_860 = 7, // Intel 80860
EM_MIPS = 8, // MIPS R3000
EM_S370 = 9, // IBM System/370
EM_MIPS_RS3_LE = 10, // MIPS RS3000 Little-endian
EM_PARISC = 15, // Hewlett-Packard PA-RISC
EM_VPP500 = 17, // Fujitsu VPP500
EM_SPARC32PLUS = 18, // Enhanced instruction set SPARC
EM_960 = 19, // Intel 80960
EM_PPC = 20, // PowerPC
EM_PPC64 = 21, // PowerPC64
EM_S390 = 22, // IBM System/390
EM_SPU = 23, // IBM SPU/SPC
EM_V800 = 36, // NEC V800
EM_FR20 = 37, // Fujitsu FR20
EM_RH32 = 38, // TRW RH-32
EM_RCE = 39, // Motorola RCE
EM_ARM = 40, // ARM
EM_ALPHA = 41, // DEC Alpha
EM_SH = 42, // Hitachi SH
EM_SPARCV9 = 43, // SPARC V9
EM_TRICORE = 44, // Siemens TriCore
EM_ARC = 45, // Argonaut RISC Core
EM_H8_300 = 46, // Hitachi H8/300
EM_H8_300H = 47, // Hitachi H8/300H
EM_H8S = 48, // Hitachi H8S
EM_H8_500 = 49, // Hitachi H8/500
EM_IA_64 = 50, // Intel IA-64 processor architecture
EM_MIPS_X = 51, // Stanford MIPS-X
EM_COLDFIRE = 52, // Motorola ColdFire
EM_68HC12 = 53, // Motorola M68HC12
EM_MMA = 54, // Fujitsu MMA Multimedia Accelerator
EM_PCP = 55, // Siemens PCP
EM_NCPU = 56, // Sony nCPU embedded RISC processor
EM_NDR1 = 57, // Denso NDR1 microprocessor
EM_STARCORE = 58, // Motorola Star*Core processor
EM_ME16 = 59, // Toyota ME16 processor
EM_ST100 = 60, // STMicroelectronics ST100 processor
EM_TINYJ = 61, // Advanced Logic Corp. TinyJ embedded processor family
EM_X86_64 = 62, // AMD x86-64 architecture
EM_PDSP = 63, // Sony DSP Processor
EM_PDP10 = 64, // Digital Equipment Corp. PDP-10
EM_PDP11 = 65, // Digital Equipment Corp. PDP-11
EM_FX66 = 66, // Siemens FX66 microcontroller
EM_ST9PLUS = 67, // STMicroelectronics ST9+ 8/16 bit microcontroller
EM_ST7 = 68, // STMicroelectronics ST7 8-bit microcontroller
EM_68HC16 = 69, // Motorola MC68HC16 Microcontroller
EM_68HC11 = 70, // Motorola MC68HC11 Microcontroller
EM_68HC08 = 71, // Motorola MC68HC08 Microcontroller
EM_68HC05 = 72, // Motorola MC68HC05 Microcontroller
EM_SVX = 73, // Silicon Graphics SVx
EM_ST19 = 74, // STMicroelectronics ST19 8-bit microcontroller
EM_VAX = 75, // Digital VAX
EM_CRIS = 76, // Axis Communications 32-bit embedded processor
EM_JAVELIN = 77, // Infineon Technologies 32-bit embedded processor
EM_FIREPATH = 78, // Element 14 64-bit DSP Processor
EM_ZSP = 79, // LSI Logic 16-bit DSP Processor
EM_MMIX = 80, // Donald Knuth's educational 64-bit processor
EM_HUANY = 81, // Harvard University machine-independent object files
EM_PRISM = 82, // SiTera Prism
EM_AVR = 83, // Atmel AVR 8-bit microcontroller
EM_FR30 = 84, // Fujitsu FR30
EM_D10V = 85, // Mitsubishi D10V
EM_D30V = 86, // Mitsubishi D30V
EM_V850 = 87, // NEC v850
EM_M32R = 88, // Mitsubishi M32R
EM_MN10300 = 89, // Matsushita MN10300
EM_MN10200 = 90, // Matsushita MN10200
EM_PJ = 91, // picoJava
EM_OPENRISC = 92, // OpenRISC 32-bit embedded processor
EM_ARC_COMPACT = 93, // ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5)
EM_XTENSA = 94, // Tensilica Xtensa Architecture
EM_VIDEOCORE = 95, // Alphamosaic VideoCore processor
EM_TMM_GPP = 96, // Thompson Multimedia General Purpose Processor
EM_NS32K = 97, // National Semiconductor 32000 series
EM_TPC = 98, // Tenor Network TPC processor
EM_SNP1K = 99, // Trebia SNP 1000 processor
EM_ST200 = 100, // STMicroelectronics (www.st.com) ST200
EM_IP2K = 101, // Ubicom IP2xxx microcontroller family
EM_MAX = 102, // MAX Processor
EM_CR = 103, // National Semiconductor CompactRISC microprocessor
EM_F2MC16 = 104, // Fujitsu F2MC16
EM_MSP430 = 105, // Texas Instruments embedded microcontroller msp430
EM_BLACKFIN = 106, // Analog Devices Blackfin (DSP) processor
EM_SE_C33 = 107, // S1C33 Family of Seiko Epson processors
EM_SEP = 108, // Sharp embedded microprocessor
EM_ARCA = 109, // Arca RISC Microprocessor
EM_UNICORE = 110, // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University
EM_EXCESS = 111, // eXcess: 16/32/64-bit configurable embedded CPU
EM_DXP = 112, // Icera Semiconductor Inc. Deep Execution Processor
EM_ALTERA_NIOS2 = 113, // Altera Nios II soft-core processor
EM_CRX = 114, // National Semiconductor CompactRISC CRX
EM_XGATE = 115, // Motorola XGATE embedded processor
EM_C166 = 116, // Infineon C16x/XC16x processor
EM_M16C = 117, // Renesas M16C series microprocessors
EM_DSPIC30F = 118, // Microchip Technology dsPIC30F Digital Signal Controller
EM_CE = 119, // Freescale Communication Engine RISC core
EM_M32C = 120, // Renesas M32C series microprocessors
EM_TSK3000 = 131, // Altium TSK3000 core
EM_RS08 = 132, // Freescale RS08 embedded processor
EM_SHARC = 133, // Analog Devices SHARC family of 32-bit DSP processors
EM_ECOG2 = 134, // Cyan Technology eCOG2 microprocessor
EM_SCORE7 = 135, // Sunplus S+core7 RISC processor
EM_DSP24 = 136, // New Japan Radio (NJR) 24-bit DSP Processor
EM_VIDEOCORE3 = 137, // Broadcom VideoCore III processor
EM_LATTICEMICO32 = 138, // RISC processor for Lattice FPGA architecture
EM_SE_C17 = 139, // Seiko Epson C17 family
EM_TI_C6000 = 140, // The Texas Instruments TMS320C6000 DSP family
EM_TI_C2000 = 141, // The Texas Instruments TMS320C2000 DSP family
EM_TI_C5500 = 142, // The Texas Instruments TMS320C55x DSP family
EM_MMDSP_PLUS = 160, // STMicroelectronics 64bit VLIW Data Signal Processor
EM_CYPRESS_M8C = 161, // Cypress M8C microprocessor
EM_R32C = 162, // Renesas R32C series microprocessors
EM_TRIMEDIA = 163, // NXP Semiconductors TriMedia architecture family
EM_HEXAGON = 164, // Qualcomm Hexagon processor
EM_8051 = 165, // Intel 8051 and variants
EM_STXP7X = 166, // STMicroelectronics STxP7x family of configurable and extensible RISC processors
EM_NDS32 = 167, // Andes Technology compact code size embedded RISC processor family
EM_ECOG1 = 168, // Cyan Technology eCOG1X family
EM_ECOG1X = 168, // Cyan Technology eCOG1X family
EM_MAXQ30 = 169, // Dallas Semiconductor MAXQ30 Core Micro-controllers
EM_XIMO16 = 170, // New Japan Radio (NJR) 16-bit DSP Processor
EM_MANIK = 171, // M2000 Reconfigurable RISC Microprocessor
EM_CRAYNV2 = 172, // Cray Inc. NV2 vector architecture
EM_RX = 173, // Renesas RX family
EM_METAG = 174, // Imagination Technologies META processor architecture
EM_MCST_ELBRUS = 175, // MCST Elbrus general purpose hardware architecture
EM_ECOG16 = 176, // Cyan Technology eCOG16 family
EM_CR16 = 177, // National Semiconductor CompactRISC CR16 16-bit microprocessor
EM_ETPU = 178, // Freescale Extended Time Processing Unit
EM_SLE9X = 179, // Infineon Technologies SLE9X core
EM_L10M = 180, // Intel L10M
EM_K10M = 181, // Intel K10M
EM_AARCH64 = 183, // ARM AArch64
EM_AVR32 = 185, // Atmel Corporation 32-bit microprocessor family
EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller
EM_TILE64 = 187, // Tilera TILE64 multicore architecture family
EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family
EM_CUDA = 190, // NVIDIA CUDA architecture
EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family
EM_CLOUDSHIELD = 192, // CloudShield architecture family
EM_COREA_1S = 193, // KIPO-KAIST Core-A 1st generation processor family
EM_COREA_2ND = 194, // KIPO-KAIST Core-A 2nd generation processor family
EM_ARC_COMPACT2 = 195, // Synopsys ARCompact V2
EM_OPEN8 = 196, // Open8 8-bit RISC soft processor core
EM_RL78 = 197, // Renesas RL78 family
EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor
EM_78KOR = 199, // Renesas 78KOR family
EM_56800EX = 200 // Freescale 56800EX Digital Signal Controller (DSC)
};
// Object file classes.
enum {
ELFCLASSNONE = 0,
ELFCLASS32 = 1, // 32-bit object file
ELFCLASS64 = 2 // 64-bit object file
};
// Object file byte orderings.
enum {
ELFDATANONE = 0, // Invalid data encoding.
ELFDATA2LSB = 1, // Little-endian object file
ELFDATA2MSB = 2 // Big-endian object file
};
// OS ABI identification.
enum {
ELFOSABI_NONE = 0, // UNIX System V ABI
ELFOSABI_HPUX = 1, // HP-UX operating system
ELFOSABI_NETBSD = 2, // NetBSD
ELFOSABI_GNU = 3, // GNU/Linux
ELFOSABI_LINUX = 3, // Historical alias for ELFOSABI_GNU.
ELFOSABI_HURD = 4, // GNU/Hurd
ELFOSABI_SOLARIS = 6, // Solaris
ELFOSABI_AIX = 7, // AIX
ELFOSABI_IRIX = 8, // IRIX
ELFOSABI_FREEBSD = 9, // FreeBSD
ELFOSABI_TRU64 = 10, // TRU64 UNIX
ELFOSABI_MODESTO = 11, // Novell Modesto
ELFOSABI_OPENBSD = 12, // OpenBSD
ELFOSABI_OPENVMS = 13, // OpenVMS
ELFOSABI_NSK = 14, // Hewlett-Packard Non-Stop Kernel
ELFOSABI_AROS = 15, // AROS
ELFOSABI_FENIXOS = 16, // FenixOS
ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000
ELFOSABI_C6000_LINUX = 65, // Linux TMS320C6000
ELFOSABI_ARM = 97, // ARM
ELFOSABI_STANDALONE = 255 // Standalone (embedded) application
};
// 段表
struct Elf32_Shdr {
Elf32_Word sh_name; // 段名,位于 .shstrtab 的字符串表。sh_name 是段名在其中的偏移
Elf32_Word sh_type; // 段类型SHT_*
Elf32_Word sh_flags; // 段标志位SHF_*
Elf32_Addr sh_addr; // 段的虚拟地址,前提是该段可被加载,否则为 0
Elf32_Off sh_offset; // 段偏移,前提是该段存在于文件中,否则无意义
Elf32_Word sh_size; // 段的长度
Elf32_Word sh_link; // 段的链接信息
Elf32_Word sh_info; // 段的额外信息
Elf32_Word sh_addralign; // 段地址对齐
Elf32_Word sh_entsize; // 项的长度
};
struct Elf64_Shdr {
Elf64_Word sh_name;
Elf64_Word sh_type;
Elf64_Xword sh_flags;
Elf64_Addr sh_addr;
Elf64_Off sh_offset;
Elf64_Xword sh_size;
Elf64_Word sh_link;
Elf64_Word sh_info;
Elf64_Xword sh_addralign;
Elf64_Xword sh_entsize;
};
// Special section indices.
enum {
SHN_UNDEF = 0, // Undefined, missing, irrelevant, or meaningless
SHN_LORESERVE = 0xff00, // Lowest reserved index
SHN_LOPROC = 0xff00, // Lowest processor-specific index
SHN_HIPROC = 0xff1f, // Highest processor-specific index
SHN_LOOS = 0xff20, // Lowest operating system-specific index
SHN_HIOS = 0xff3f, // Highest operating system-specific index
SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation
SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables
SHN_XINDEX = 0xffff, // Mark that the index is >= SHN_LORESERVE
SHN_HIRESERVE = 0xffff // Highest reserved index
};
// Section types.
enum : unsigned {
SHT_NULL = 0, // No associated section (inactive entry).
SHT_PROGBITS = 1, // Program-defined contents.
SHT_SYMTAB = 2, // Symbol table.
SHT_STRTAB = 3, // String table.
SHT_RELA = 4, // Relocation entries; explicit addends.
SHT_HASH = 5, // Symbol hash table.
SHT_DYNAMIC = 6, // Information for dynamic linking.
SHT_NOTE = 7, // Information about the file.
SHT_NOBITS = 8, // Data occupies no space in the file.
SHT_REL = 9, // Relocation entries; no explicit addends.
SHT_SHLIB = 10, // Reserved.
SHT_DYNSYM = 11, // Symbol table.
SHT_INIT_ARRAY = 14, // Pointers to initialization functions.
SHT_FINI_ARRAY = 15, // Pointers to termination functions.
SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
SHT_GROUP = 17, // Section group.
SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type.
SHT_ARM_EXIDX = 0x70000001U, // Exception Index table
SHT_ARM_PREEMPTMAP = 0x70000002U, // BPABI DLL dynamic linking pre-emption map
SHT_ARM_ATTRIBUTES = 0x70000003U, // Object file compatibility attributes
SHT_ARM_DEBUGOVERLAY = 0x70000004U,
SHT_ARM_OVERLAYSECTION = 0x70000005U,
SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in this section based on their sizes
SHT_X86_64_UNWIND = 0x70000001, // Unwind information
SHT_MIPS_REGINFO = 0x70000006, // Register usage information
SHT_MIPS_OPTIONS = 0x7000000d, // General options
SHT_MIPS_ABIFLAGS = 0x7000002a, // Abiflags options
SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
};
// Section flags.
enum : unsigned {
// Section data should be writable during execution.
SHF_WRITE = 0x1,
// Section occupies memory during program execution.
SHF_ALLOC = 0x2,
// Section contains executable machine instructions.
SHF_EXECINSTR = 0x4,
// The data in this section may be merged.
SHF_MERGE = 0x10,
// The data in this section is null-terminated strings.
SHF_STRINGS = 0x20,
// A field in this section holds a section header table index.
SHF_INFO_LINK = 0x40U,
// Adds special ordering requirements for link editors.
SHF_LINK_ORDER = 0x80U,
// This section requires special OS-specific processing to avoid incorrect
// behavior.
SHF_OS_NONCONFORMING = 0x100U,
// This section is a member of a section group.
SHF_GROUP = 0x200U,
// This section holds Thread-Local Storage.
SHF_TLS = 0x400U,
// This section is excluded from the final executable or shared library.
SHF_EXCLUDE = 0x80000000U,
// Start of target-specific flags.
/// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped
/// together by the linker to form the constant pool and the cp register is
/// set to the start of the constant pool by the boot code.
XCORE_SHF_CP_SECTION = 0x800U,
/// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped
/// together by the linker to form the data section and the dp register is
/// set to the start of the section by the boot code.
XCORE_SHF_DP_SECTION = 0x1000U,
SHF_MASKOS = 0x0ff00000,
// Bits indicating processor-specific flags.
SHF_MASKPROC = 0xf0000000,
// If an object file section does not have this flag set, then it may not hold
// more than 2GB and can be freely referred to in objects using smaller code
// models. Otherwise, only objects using larger code models can refer to them.
// For example, a medium code model object can refer to data in a section that
// sets this flag besides being able to refer to data in a section that does
// not set it; likewise, a small code model object can refer only to code in a
// section that does not set this flag.
SHF_X86_64_LARGE = 0x10000000,
// All sections with the GPREL flag are grouped into a global data area
// for faster accesses
SHF_HEX_GPREL = 0x10000000,
// Section contains text/data which may be replicated in other sections.
// Linker must retain only one copy.
SHF_MIPS_NODUPES = 0x01000000,
// Linker must generate implicit hidden weak names.
SHF_MIPS_NAMES = 0x02000000,
// Section data local to process.
SHF_MIPS_LOCAL = 0x04000000,
// Do not strip this section.
SHF_MIPS_NOSTRIP = 0x08000000,
// Section must be part of global data area.
SHF_MIPS_GPREL = 0x10000000,
// This section should be merged.
SHF_MIPS_MERGE = 0x20000000,
// Address size to be inferred from section entry size.
SHF_MIPS_ADDR = 0x40000000,
// Section data is string data by default.
SHF_MIPS_STRING = 0x80000000
};
// Section Group Flags
enum : unsigned {
GRP_COMDAT = 0x1,
GRP_MASKOS = 0x0ff00000,
GRP_MASKPROC = 0xf0000000
};
// 符号信息
struct Elf32_Sym {
Elf32_Word st_name; // 符号名字,包含了该符号名在字符串表中的下标
Elf32_Addr st_value; // 符号相对应的值,是一个绝对值,或地址等。不同的符号,含义不同
Elf32_Word st_size; // 符号的大小
unsigned char st_info; // 符号的类型和绑定信息
unsigned char st_other; // 目前为 0保留
Elf32_Half st_shndx; // 符号所在段的下标
};
struct Elf64_Sym {
Elf64_Word st_name; // Symbol name (index into string table)
unsigned char st_info; // Symbol's type and binding attributes
unsigned char st_other; // Must be zero; reserved
Elf64_Half st_shndx; // Which section (header tbl index) it's defined in
Elf64_Addr st_value; // Value or address associated with the symbol
Elf64_Xword st_size; // Size of the symbol
};
// Relocation entry, without explicit addend.
struct Elf32_Rel {
Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf32_Word r_info; // Symbol table index and type of relocation to apply
};
// Relocation entry with explicit addend.
struct Elf32_Rela {
Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf32_Word r_info; // Symbol table index and type of relocation to apply
Elf32_Sword r_addend; // Compute value for relocatable field by adding this
};
// Relocation entry, without explicit addend.
struct Elf64_Rel {
Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr).
Elf64_Xword r_info; // Symbol table index and type of relocation to apply.
};
// Relocation entry with explicit addend.
struct Elf64_Rela {
Elf64_Addr r_offset; // Location (file byte offset, or program virtual addr).
Elf64_Xword r_info; // Symbol table index and type of relocation to apply.
Elf64_Sxword r_addend; // Compute value for relocatable field by adding this.
};
#endif // !ELF_H

View File

@ -1,39 +0,0 @@
#include "Formatter.h"
#include <cstdlib>
#include <cstring>
#include <iostream>
// TODO: 前面填充 0。
char const * Formatter::binary_8_bit(uint8_t n)
{
char buffer[8 + 1];
memset(buffer, 0, 8 + 1);
// _itoa_s(n, buffer, 2);
return buffer;
}
char const* Formatter::binary_16_bit(uint16_t n)
{
char buffer[16 + 1];
memset(buffer, 0, 16 + 1);
// itoa_s(n, buffer, 2);
return buffer;
}
char const* Formatter::binary_32_bit(uint32_t n)
{
char buffer[32 + 1];
memset(buffer, 0, 32 + 1);
// _itoa_s(n, buffer, 2);
return buffer;
}
char const* Formatter::binary_64_bit(uint64_t n)
{
char buffer[64 + 1];
memset(buffer, 0, 64 + 1);
// _itoa_s(n, buffer, 2);
return buffer;
}

View File

@ -1,15 +0,0 @@
#ifndef FORMAT_H_
#define FORMAT_H_
#include <cstdint>
class Formatter
{
public:
static char const* binary_8_bit(uint8_t n);
static char const* binary_16_bit(uint16_t n);
static char const* binary_32_bit(uint32_t n);
static char const* binary_64_bit(uint64_t n);
};
#endif // !FORMAT_H_

View File

@ -1,43 +0,0 @@
#include "Printer.h"
#include "Formatter.h"
#include <iostream>
void Printer::print_ushort_hex_array(uint16_t const* array, const unsigned int size)
{
for (unsigned int i = 0; i < size; i++)
printf("%.4x ", array[i]);
printf("\n");
}
void Printer::print_int_array(int const* array, const unsigned int size)
{
for (unsigned int i = 0; i < size; i++)
printf("%d ", array[i]);
printf("\n");
}
void Printer::print_hex_array(uint8_t const* array, const unsigned int size)
{
for (unsigned int i = 0; i < size; i++)
printf("%.2x ", array[i]);
printf("\n");
}
void Printer::print_hex_array2(uint16_t const* array, const unsigned int size)
{
for (unsigned int i = 0; i < size; i++)
printf("%.4x ", array[i]);
printf("\n");
}
void Printer::print_char_array(unsigned char const* array, const unsigned int size)
{
for (unsigned int i = 0; i < size; i++)
printf("%.2x ", array[i]);
printf("\n");
}

View File

@ -1,15 +0,0 @@
#ifndef PRINTER_H
#define PRINTER_H
#include <cstdint>
class Printer
{
public:
static void print_ushort_hex_array(uint16_t const* array, const unsigned int size);
static void print_int_array(int const* array, const unsigned int size);
static void print_hex_array(uint8_t const* array, const unsigned int size);
static void print_hex_array2(uint16_t const* array, const unsigned int size);
static void print_char_array(unsigned char const* array, const unsigned int size);
};
#endif // !PRINTER_H

View File

@ -1,5 +0,0 @@
target("zelf")
set_rundir(".")
set_kind("binary")
add_files("src/*.cpp","src/**/*.cpp")
add_headerfiles("src/*.h","src/**/*.h")

View File

@ -27,10 +27,6 @@ bool Coff64::CheckFile(IArchive& Ar)
return true;
}
void Coff64::PrintTest()
{
}
Coff64::~Coff64()
{
if (!IsSerialize)

View File

@ -17,7 +17,6 @@ public:
public:
virtual void Serialize(IArchive& Ar) override;
virtual bool CheckFile(IArchive& Ar) override;
virtual void PrintTest() override;
public:
~Coff64();
};

View File

@ -26,7 +26,10 @@ class IArchive
public:
virtual void Seek(int start = -1, int offset = -1) = 0;
virtual void Serialize(void* data, int size) = 0;
virtual void Serialize(void* data) = 0;
void Serialize(void* data)
{
Serialize(data, 0);
}
private:
};
@ -36,6 +39,7 @@ protected:
int Start = 0;
int Stop = 0;
int Size = 0;
bool SwapBytes = false;
char* Data = nullptr;
public:
FArchive(char* file);
@ -58,11 +62,10 @@ public:
appError("Serializing behind stopper (%X+%X > %X)", pos, size, Stop);
else if (pos + size > Size)
appError("Serializing behind end of buffer");
if (SwapBytes) {
}
memcpy(data, Data + pos, size);
Pos += size;
}
virtual void Serialize(void* data) override
{
Serialize(data, 0);
}
};

View File

@ -1,12 +1,19 @@
#pragma once
#include "Archive.h"
class IPackage;
class IPackageExpansion {
public:
void Expansion(IPackage& pack) {};
};
class IPackage {
protected:
bool IsSerialize = false;
public:
virtual void Serialize(IArchive& Ar) = 0;
virtual bool CheckFile(IArchive& Ar) = 0;
virtual void PrintTest() = 0;
void Expansion(IPackageExpansion& exp) {
exp.Expansion(*this);
};
private:
};

View File

@ -15,10 +15,9 @@ void Elf64::Serialize(IArchive& Ar)
}
for (int i = 0; i < e_shnum; i++) {
Elf64_Shdr& shdr = ShdrList[i];
Ar.Seek(Ehdr.e_shoff + i * sizeof(shdr), sizeof(shdr));
Ar.Serialize(&shdr);
ELF64_Shdr_Data& shdr_data = ShdrDataList[i];
shdr_data.Serialize(Ar, shdr);
Ar.Seek(Ehdr.e_shoff + i * sizeof(shdr), sizeof(shdr));
Ar << shdr << shdr_data;
}
}
@ -31,17 +30,6 @@ bool Elf64::CheckFile(IArchive& Ar)
return false;
return true;
}
void Elf64::PrintTest()
{
int e_shnum = Ehdr.e_shnum;
for (int i = 0; i < e_shnum; i++) {
Elf64_Shdr& shdr = ShdrList[i];
ELF64_Shdr_Data& shdr_data = ShdrDataList[i];
std::cout << i << shdr.sh_name << GetShStrById(shdr.sh_name) << std::endl;
}
}
Elf64::~Elf64()
{
if (!IsSerialize)
@ -55,7 +43,6 @@ Elf64::~Elf64()
appFree(ShdrList);
appFree(ShdrDataList);
}
char* Elf64::GetShStrByPos(int pos)
{
int e_shstrndx = Ehdr.e_shstrndx;
@ -102,4 +89,17 @@ char* ELF64_Shdr_Data::GetStrById(int id)
}
i = i < Size ? i : 0;
return &Data[i];
}
}
IArchive& operator<<(IArchive& Ar, Elf64_Shdr& shdr)
{
Ar.Serialize(&shdr, sizeof(shdr));
Ar.Seek(shdr.sh_offset, shdr.sh_size);
return Ar;
}
IArchive& operator<<(IArchive& Ar, ELF64_Shdr_Data& shdr_data)
{
Ar.Serialize(&shdr_data);
return Ar;
}

View File

@ -19,9 +19,10 @@ public:
public:
virtual void Serialize(IArchive& Ar) override;
virtual bool CheckFile(IArchive& Ar) override;
virtual void PrintTest() override;
public:
~Elf64();
friend IArchive& operator<<(IArchive& Ar, Elf64_Shdr& shdr);
friend IArchive& operator<<(IArchive& Ar, ELF64_Shdr_Data& shdr_data);
public:
char* GetShStrByPos(int pos);
char* GetShStrById(int pos);

View File

@ -15,12 +15,10 @@ int main(int argc, char** argv)
FArchive Ar("file/SimpleSection.o");
if (Elf.CheckFile(Ar)) {
Elf.Serialize(Ar);
Elf.PrintTest();
}
Coff64 Coff;
if (Coff.CheckFile(Ar)) {
Coff.Serialize(Ar);
Coff.PrintTest();
}
free(data);
cout << "hello world!" << endl;

View File

@ -49,7 +49,7 @@ int TPoint::static_int_a = 0;
static int static_int_a = -1;
void TestMemory() {
//对象内存布局
//对象内存布局
TPoint p1(1, 2),p2(2,4);
TPointSon ps(2 , 3);
uint8_t* ptr_u = (uint8_t*) &ps;
@ -58,8 +58,6 @@ void TestMemory() {
LOG_INFO("{} {}", typeid(p1).name(),typeid(ps).name());
LOG_INFO("class size = {} object size = {}", sizeof(TPoint), sizeof(p1));
LOG_INFO("class static addr = {} static addr = {}", (void*)&TPoint::static_int_a, (void*)&static_int_a);
auto a = 1;
auto b = FPTR(&TPoint::TestStaticFunction);
TPoint::TestStaticFunction();
p1.Testvirtual();
typedef void (TPoint::* FuncPointer)();
@ -69,16 +67,14 @@ void TestMemory() {
(p2.*fp2)();
p2.Testvirtua2();
std::cout << &TPoint::TestStaticFunction << &TPoint::Testvirtual << &TPoint::Testvirtua2;
//LOG_INFO("class static function addr = {} class virtual function addr = = {}", FPTR(&TPoint::TestStaticFunction), a);
//LOG_INFO("class static function addr = {} class virtual function addr = = {}", LPTR(&TPoint::TestStaticFunction), LPTR(&TPoint::Testvirtual));
//打印对象内存
//打印对象内存
bool* ip = (bool*)&p1;
//LOG_INFO("object hex addr = {}", *(int*)ip);
LOG_INFO("object hex addr = {}", *(int*)ip);
for (int i = 0; i < sizeof(TPoint); i++) {
if (i % 4 == 0) {
//LOG_INFO("object hex addr = {}{}", *(int*)(ip + i),(int*) * (int*)(ip + i));
//LOG_INFO("object hex addr = {}{}", *(int*)(ip + i), (int*) * (int*)(ip + i));
}
//LOG_INFO(" {} ", *(ip + i));
LOG_INFO(" {} ", *(ip + i));
}
LOG_INFO("");
}

View File

@ -33,7 +33,7 @@ public:
int change(int a) {
return a - 100;
}
//值传递
//值传递
void ValuePassing(Rect rc ,int ai) {
int a = rc.a;
rc.a = change(rc.a);
@ -46,7 +46,7 @@ void ValuePassing(Rect rc ,int ai) {
cout << "parmar ai = " << ai << endl;
}
//引用传递
//引用传递
void ReferencePassing(Rect& rc, int& ai) {
int a = rc.a;
rc.a = change(rc.a);
@ -58,7 +58,7 @@ void ReferencePassing(Rect& rc, int& ai) {
cout << "parmar a = " << a << " :" << rc.a << " , return value = " << rc.obj.value << " :" << obj.value << endl;
cout << "parmar ai = " << ai << endl;
}
//指针传递
//指针传递
void PointPassing(Rect* rc_ptr, int* ai) {
Rect& rc = *rc_ptr;
int a = rc.a;
@ -74,7 +74,7 @@ void PointPassing(Rect* rc_ptr, int* ai) {
void pt(int a , int b , int c , string str) {
cout << "parameter " << a << endl;
}
//展开函数
//展开函数
template <typename ...TArgs>
void print(int a , TArgs... Args)
{
@ -83,7 +83,7 @@ void print(int a , TArgs... Args)
}
void TestParmeter()
{
//函数实参和形参
//函数实参和形参
cout << "\t\t TestParmeter" << endl;
Rect rc;
int ai = 1;

View File

@ -32,7 +32,7 @@ void TestReflex() {
TPoint p1;
TPoint p2;
int x = 0;
//反射 虚函数 静态函数
//反射 虚函数 静态函数
cout << "\t\t TestReflex" << endl;
cout << "size = " << sizeof(p1) << endl;
cout << "size = " << sizeof(TPoint) << endl;

View File

@ -21,11 +21,11 @@ void Template2()
{
void (*FPii)(int&, int&);
FPii = Swap; //函数指针FPii
FPii = Swap; //函数指针FPii
void (*FPff)(float&, float&);
FPff = Swap; //函数指针FPff
FPff = Swap; //函数指针FPff
cout << reinterpret_cast<void*>(FPii) << endl;
cout << reinterpret_cast<void*>(FPff) << endl;

View File

@ -1,2 +0,0 @@
#include "log.h"
LogSystem gLog;

View File

@ -1,19 +1 @@
#include "log/log_system.h"
extern LogSystem gLog;
template<typename F>
void* FPTR(F f) {
return (void*)f;
}
#define LOG_HELPER(LOG_LEVEL, ...) \
gLog.log(LOG_LEVEL, "[" + std::string(__FUNCTION__) + "] " + __VA_ARGS__);
#define LOG_DEBUG(...) LOG_HELPER(LogSystem::LogLevel::debug, __VA_ARGS__);
#define LOG_INFO(...) LOG_HELPER(LogSystem::LogLevel::info, __VA_ARGS__);
#define LOG_WARN(...) LOG_HELPER(LogSystem::LogLevel::warn, __VA_ARGS__);
#define LOG_ERROR(...) LOG_HELPER(LogSystem::LogLevel::error, __VA_ARGS__);
#define LOG_FATAL(...) LOG_HELPER(LogSystem::LogLevel::fatal, __VA_ARGS__);

View File

@ -1,9 +1,9 @@
//#include <iostream>
#include "ZGrammar/Grammar.h"
#include "ZGrammar/Class.h"
using namespace std;
int main()
//using namespace std;
int main(int argc, char** argv)
{
TestClass();
return 0;
//cout << "hello world!" << endl;
return 0;
}

View File

@ -0,0 +1,44 @@
#pragma once
#include <iostream>
using namespace std;
void pass_value(int a,int* b, int& c1,const int& c2, int&& c3, const int&& c4) {
char buf[1024];
sprintf(buf, "%d %d %d %d %d %d",
a, *b, c1, c2 , c3 , c4);
cout << "pass_value::" << buf << "\n";
a--; (*b)--; c1--; c3--;
sprintf(buf, "int a = %d int* b = %d, int& c1 = %d,const int& c2 = %d, int&& c3 = %d, const int&& c4 = %d",
a, *b, c1, c2, c3, c4);
cout << "change_value::" << buf << "\n\n";
}
template<typename T>
void pass_templpate(int a, int* b, T&& c) {
char buf[1024];
sprintf(buf, "%d %d %d",a, *b, c);
cout << "pass_value::" << buf << "\n";
a--; (*b)--; c--;
sprintf(buf, "int a = %d int* b = %d, T&& c = %d",
a, *b, c);
cout << "change_value::" << buf << "\n\n";
}
void test1() {
#define Value 99
int i = Value;
pass_value(i, &i, i , i , Value, Value);
pass_value(i, &i, i, Value, Value, Value);
//pass_value(i, 0, i, i, Value, Value);
//值传递,代价大,不能修改原始数据
//指针需要检测判空
//左值引用只能接收左值
//常左值引用可以接收左值和右值,但不能修改
//右值引用只能接收右值
//右值引用模板可以实现万能引用,实现完美转发
pass_templpate(i, &i, i);
pass_templpate(i, &i, Value);
}
void main()
{
//函数实参和形参
cout << "\t\t TestParmeter" << endl;
test1();
}

View File

@ -4,4 +4,8 @@ target("zplus")
set_kind("binary")
add_includedirs("src", {public = true})
add_files("src/*.cpp","src/**/*.cpp")
add_headerfiles("src/*.h","src/**/*.h")
add_headerfiles("src/**/*.h")
target("zplus_fun01_parameter")
set_kind("binary")
add_files("test/fun01_parameter.cpp")

View File

@ -0,0 +1,26 @@
local lua_xmake = [[
local kind = "%s"
add_rules("mode.debug", "mode.release")
set_arch("x64")
set_languages("cxx20")
add_requires("UTemplate","USmallFlat")
target("UDRefl")
set_kind(kind)
add_packages("UTemplate","USmallFlat")
add_includedirs("include")
add_files("src/core/**.cpp")
add_headerfiles("include/**.hpp","include/**.h")
]]
package("UDRefl")
set_urls("https://github.com/Ubpa/UDRefl.git")
add_includedirs("include")
add_deps("UTemplate","USmallFlat")
on_install("macosx", "linux", "windows", function (package)
io.writefile("xmake.lua", format(lua_xmake,"static"))
--local configs = {kind = "static"}
package:config_set("debug",true)
os.cp("include", package:installdir())
import("package.tools.xmake").install(package)
--import("package.tools.xmake").install(package)
end)

View File

@ -0,0 +1,9 @@
package("USRefl")
add_deps("UTemplate","USmallFlat")
set_kind("library", {headeronly = true})
set_urls("https://github.com/Ubpa/USRefl.git")
add_includedirs("include")
on_install(function (package)
os.cp("include", package:installdir())
end)

View File

@ -0,0 +1,8 @@
package("USmallFlat")
set_kind("library", {headeronly = true})
set_urls("https://github.com/Ubpa/USmallFlat.git")
add_includedirs("include")
on_install(function (package)
os.cp("include", package:installdir())
end)

View File

@ -0,0 +1,7 @@
package("UTemplate")
set_kind("library", {headeronly = true})
set_urls("https://github.com/Ubpa/UTemplate.git")
add_includedirs("include")
on_install(function (package)
os.cp("include", package:installdir())
end)

View File

@ -1,3 +1,3 @@
add_requires("spdlog")
includes("**/xmake.lua")
includes("**/xmake.lua|ubpa/**/xmake.lua")