upload
This commit is contained in:
parent
35968cabd5
commit
ec5ce69a80
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal 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
8
.idea/modules.xml
generated
Normal 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
6
.idea/vcs.xml
generated
Normal 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
9
.idea/zlib.iml
generated
Normal 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>
|
||||
1
src/ReflTest/src/TestUDRefl.cpp
Normal file
1
src/ReflTest/src/TestUDRefl.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "TestUDRefl.h"
|
||||
40
src/ReflTest/src/TestUDRefl.h
Normal file
40
src/ReflTest/src/TestUDRefl.h
Normal 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;
|
||||
}
|
||||
1
src/ReflTest/src/TestUSRefl.cpp
Normal file
1
src/ReflTest/src/TestUSRefl.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "TestUSRefl.h"
|
||||
45
src/ReflTest/src/TestUSRefl.h
Normal file
45
src/ReflTest/src/TestUSRefl.h
Normal 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
102
src/ReflTest/src/main.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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
|
||||
@ -1,9 +0,0 @@
|
||||
//#include <iostream>
|
||||
|
||||
//using namespace std;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
//cout << "hello world!" << endl;
|
||||
return 0;
|
||||
}
|
||||
@ -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__);
|
||||
0
src/zcoro/include/zcoro/task.h
Normal file
0
src/zcoro/include/zcoro/task.h
Normal file
64
src/zcoro/include/zthread/channel.h
Normal file
64
src/zcoro/include/zthread/channel.h
Normal 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
71
src/zcoro/main.cpp
Normal 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();
|
||||
}
|
||||
0
src/zcoro/src/zcoro/co_context.cpp
Normal file
0
src/zcoro/src/zcoro/co_context.cpp
Normal file
103
src/zcoro/test/01mutex.cpp
Normal file
103
src/zcoro/test/01mutex.cpp
Normal 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;
|
||||
}
|
||||
56
src/zcoro/test/02condition.cpp
Normal file
56
src/zcoro/test/02condition.cpp
Normal 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;
|
||||
}
|
||||
66
src/zcoro/test/03semaphore.cpp
Normal file
66
src/zcoro/test/03semaphore.cpp
Normal 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;
|
||||
}
|
||||
50
src/zcoro/test/04promise.cpp
Normal file
50
src/zcoro/test/04promise.cpp
Normal 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
29
src/zcoro/xmake.lua
Normal 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
38
src/zelf/.gitignore
vendored
@ -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.
@ -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;
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
@ -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_flag,machine 为平台,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; // 段的物理装载地址,即 LMA(Load 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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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_
|
||||
@ -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");
|
||||
}
|
||||
@ -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
|
||||
@ -1,5 +0,0 @@
|
||||
target("zelf")
|
||||
set_rundir(".")
|
||||
set_kind("binary")
|
||||
add_files("src/*.cpp","src/**/*.cpp")
|
||||
add_headerfiles("src/*.h","src/**/*.h")
|
||||
@ -27,10 +27,6 @@ bool Coff64::CheckFile(IArchive& Ar)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Coff64::PrintTest()
|
||||
{
|
||||
}
|
||||
|
||||
Coff64::~Coff64()
|
||||
{
|
||||
if (!IsSerialize)
|
||||
|
||||
@ -17,7 +17,6 @@ public:
|
||||
public:
|
||||
virtual void Serialize(IArchive& Ar) override;
|
||||
virtual bool CheckFile(IArchive& Ar) override;
|
||||
virtual void PrintTest() override;
|
||||
public:
|
||||
~Coff64();
|
||||
};
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
@ -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:
|
||||
|
||||
};
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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("");
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
#include "log.h"
|
||||
LogSystem gLog;
|
||||
@ -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__);
|
||||
@ -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;
|
||||
}
|
||||
44
src/zplus/test/fun01_parameter.cpp
Normal file
44
src/zplus/test/fun01_parameter.cpp
Normal 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();
|
||||
}
|
||||
@ -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")
|
||||
26
thridpart/ubpa/UDRefl/xmake.lua
Normal file
26
thridpart/ubpa/UDRefl/xmake.lua
Normal 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)
|
||||
9
thridpart/ubpa/USRefl/xmake.lua
Normal file
9
thridpart/ubpa/USRefl/xmake.lua
Normal 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)
|
||||
8
thridpart/ubpa/USmallFlat/xmake.lua
Normal file
8
thridpart/ubpa/USmallFlat/xmake.lua
Normal 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)
|
||||
7
thridpart/ubpa/UTemplate/xmake.lua
Normal file
7
thridpart/ubpa/UTemplate/xmake.lua
Normal 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)
|
||||
@ -1,3 +1,3 @@
|
||||
|
||||
add_requires("spdlog")
|
||||
includes("**/xmake.lua")
|
||||
includes("**/xmake.lua|ubpa/**/xmake.lua")
|
||||
Loading…
Reference in New Issue
Block a user