Merge commit '634f6ff006c8811c47a7a07356f46214f5d8a736' as 'external/ircolib'
@@ -1,56 +0,0 @@
|
||||
---
|
||||
Language: Cpp
|
||||
BasedOnStyle: LLVM
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignOperands: false
|
||||
AlignTrailingComments: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: true
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
ColumnLimit: 120
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
IndentAccessModifiers: false
|
||||
AccessModifierOffset: 0
|
||||
ContinuationIndentWidth: 0
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*'
|
||||
Priority: 1
|
||||
- Regex: '^".*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||
IndentCaseBlocks: true
|
||||
InsertNewlineAtEOF: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
SortIncludes: Never
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: Inner
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
TabWidth: 4
|
||||
IndentWidth: 4
|
||||
...
|
||||
@@ -1,4 +0,0 @@
|
||||
CompileFlags:
|
||||
CompilationDatabase: build/
|
||||
Completion:
|
||||
HeaderInsertion: Never
|
||||
@@ -1,3 +0,0 @@
|
||||
tests/
|
||||
build/
|
||||
.vscode/
|
||||
@@ -1,33 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
project(weee CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
option(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
include_directories(external/ELFIO)
|
||||
include_directories(external/capstone/include)
|
||||
include_directories(external/cflags/include)
|
||||
include_directories(external/SDL/include)
|
||||
include_directories(external/xbyak)
|
||||
include_directories(external)
|
||||
|
||||
if(WIN32)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
add_compile_definitions(NOMINMAX)
|
||||
endif()
|
||||
add_compile_options(-fno-operator-names)
|
||||
|
||||
set(CAPSTONE_ARCHITECTURE_DEFAULT OFF)
|
||||
set(CAPSTONE_PPC_SUPPORT ON)
|
||||
add_subdirectory(external/capstone)
|
||||
add_subdirectory(external/SDL)
|
||||
|
||||
add_executable(weee main.cpp core/mem.cpp core/loaders/elf.cpp
|
||||
core/loaders/dol.cpp
|
||||
core/broadway.cpp
|
||||
core/broadway/instructions.cpp
|
||||
core/broadway/mmio/vi.cpp)
|
||||
target_link_libraries(weee PUBLIC SDL3::SDL3 capstone)
|
||||
target_include_directories(weee PUBLIC core)
|
||||
@@ -1,9 +1,7 @@
|
||||
# weee
|
||||
|
||||
- [x] ELF
|
||||
- [x] DOL
|
||||
- [x] panda.dol
|
||||
- [ ] libogc simple examples
|
||||
|
||||
## Cool people
|
||||
- [layle](https://github.com/ioncodes/), thanks for the IDA plugins and resources. Check out [*his* Wii emulator](https://github.com/ioncodes/gecko)
|
||||
# ircolib
|
||||
|
||||
Collections of useful functions I started copy-pasting in various projects and thus decided to gather all in one place.
|
||||
|
||||
## Flags
|
||||
|
||||
To enable SIMD for `floats.hpp`, add a `#define SIMD_SUPPORT` before `#include "floats.hpp"`.
|
||||
@@ -1,193 +0,0 @@
|
||||
#include <broadway/utils.hpp>
|
||||
#include <mem.hpp>
|
||||
#include <print>
|
||||
#include <ircolib/log.hpp>
|
||||
#include <ircolib/mem_access.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace weee::core {
|
||||
broadway::broadway() {
|
||||
if (cs_open(CS_ARCH_PPC, cs_mode(CS_MODE_BIG_ENDIAN | CS_MODE_32), &capstone) != CS_ERR_OK) {
|
||||
std::println("warning: could not initialize capstone. Disassembly is disabled");
|
||||
disasm_available = false;
|
||||
}
|
||||
}
|
||||
|
||||
void broadway::set_pc(ircolib::u32 value) { pc = value; }
|
||||
|
||||
void broadway::run(mem &mem) {
|
||||
for (int i = 0; i < 12150000; i++) {
|
||||
// std::println("pc: 0x{:08X}", pc);
|
||||
execute(fetch(mem), mem);
|
||||
}
|
||||
}
|
||||
|
||||
ircolib::u32 broadway::fetch(mem &mem) {
|
||||
ircolib::u32 val = mem.read32(pc)
|
||||
.and_then([&](ircolib::u32 val) { return std::expected<ircolib::u32, std::string>(val); })
|
||||
.or_else([&](std::string e) {
|
||||
ircolib::panic("broadway read failed. Reason {} (pc: 0x{:08X})", e, pc);
|
||||
return std::expected<ircolib::u32, std::string>();
|
||||
})
|
||||
.value();
|
||||
pc += 4;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void broadway::decode_special3(ircolib::u32 instr, mem &mem) {
|
||||
auto secondary = utils::secondary(instr);
|
||||
switch (secondary) {
|
||||
case 38:
|
||||
mtfsb1(instr);
|
||||
break;
|
||||
case 711:
|
||||
mtfsf(instr);
|
||||
break;
|
||||
default:
|
||||
ircolib::panic("broadway unknown special3 {} (0x{:04X}) (pc 0x{:08X})", secondary, secondary, pc - 4);
|
||||
}
|
||||
}
|
||||
|
||||
void broadway::decode_special2(ircolib::u32 instr, mem &mem) {
|
||||
auto secondary = utils::secondary(instr);
|
||||
switch (secondary) {
|
||||
case 0x000:
|
||||
cmp(instr);
|
||||
break;
|
||||
case 0x020:
|
||||
cmpl(instr);
|
||||
break;
|
||||
case 0x028:
|
||||
subf(instr);
|
||||
break;
|
||||
case 0x053:
|
||||
mfmsr(instr);
|
||||
break;
|
||||
case 0x0D2:
|
||||
ircolib::warn("broadway TODO mtsr (pc 0x{:08X})", pc - 4);
|
||||
break;
|
||||
case 0x1BC:
|
||||
or (instr);
|
||||
break;
|
||||
case 0x153:
|
||||
case 0x1D3:
|
||||
mftspr(ircolib::is_bit_set<ircolib::u32, 7>(secondary), instr);
|
||||
break;
|
||||
case 0x1DC:
|
||||
nand(instr);
|
||||
break;
|
||||
case 0x10A:
|
||||
add(instr);
|
||||
break;
|
||||
case 0x256: // sync
|
||||
break;
|
||||
default:
|
||||
ircolib::panic("broadway unknown special2 {} (0x{:04X}) (pc 0x{:08X})", secondary, secondary, pc - 4);
|
||||
}
|
||||
}
|
||||
|
||||
void broadway::decode_special1(ircolib::u32 instr, mem &mem) {
|
||||
switch (utils::secondary(instr)) {
|
||||
case 0x10:
|
||||
bclrx(instr);
|
||||
break;
|
||||
case 0x32:
|
||||
rfi(instr);
|
||||
break;
|
||||
case 0x96: // isync
|
||||
break;
|
||||
default:
|
||||
ircolib::panic("broadway unknown special1 {} (0x{:04X}) (pc 0x{:08X})", utils::secondary(instr),
|
||||
utils::secondary(instr), pc - 4);
|
||||
}
|
||||
}
|
||||
|
||||
void broadway::execute(ircolib::u32 instr, mem &mem) {
|
||||
switch (utils::primary(instr)) {
|
||||
case 10:
|
||||
cmpli(instr);
|
||||
break;
|
||||
case 11:
|
||||
cmpi(instr);
|
||||
break;
|
||||
case 14:
|
||||
addi(instr);
|
||||
break;
|
||||
case 15:
|
||||
addis(instr);
|
||||
break;
|
||||
case 16:
|
||||
bcx(instr);
|
||||
break;
|
||||
case 18:
|
||||
bx(instr);
|
||||
break;
|
||||
case 19:
|
||||
decode_special1(instr, mem);
|
||||
break;
|
||||
case 21:
|
||||
rlwinm(instr);
|
||||
break;
|
||||
case 24:
|
||||
ori(instr);
|
||||
break;
|
||||
case 25:
|
||||
oris(instr);
|
||||
break;
|
||||
case 28:
|
||||
andi(instr);
|
||||
break;
|
||||
case 31:
|
||||
decode_special2(instr, mem);
|
||||
break;
|
||||
case 32:
|
||||
lwz(instr, mem);
|
||||
break;
|
||||
case 33:
|
||||
lwzu(instr, mem);
|
||||
break;
|
||||
case 36:
|
||||
stw(instr, mem);
|
||||
break;
|
||||
case 37:
|
||||
stwu(instr, mem);
|
||||
break;
|
||||
case 39:
|
||||
stbu(instr, mem);
|
||||
break;
|
||||
case 44:
|
||||
sth(instr, mem);
|
||||
break;
|
||||
case 50:
|
||||
lfd(instr, mem);
|
||||
break;
|
||||
case 63:
|
||||
decode_special3(instr, mem);
|
||||
break;
|
||||
default:
|
||||
std::println("broadway::execute unimplemented instruction 0x{:08X} / 0b{:032b}", instr, instr);
|
||||
std::println("disassembly:");
|
||||
print_disasm(instr);
|
||||
ircolib::panic("");
|
||||
}
|
||||
}
|
||||
|
||||
void broadway::print_disasm(ircolib::u32 instr) {
|
||||
if (!disasm_available)
|
||||
return;
|
||||
|
||||
cs_insn *insn;
|
||||
auto instr_buff = ircolib::integral_to_slice(std::byteswap(instr));
|
||||
size_t count = cs_disasm(capstone, instr_buff.data(), instr_buff.size(), pc - 4, 1, &insn);
|
||||
if (count <= 0)
|
||||
return;
|
||||
|
||||
size_t j;
|
||||
for (j = 0; j < count; j++) {
|
||||
std::println("\t0x{:x}:\t{}\t\t{}", insn[j].address, insn[j].mnemonic, insn[j].op_str);
|
||||
}
|
||||
|
||||
cs_free(insn, count);
|
||||
}
|
||||
} // namespace weee::core
|
||||
@@ -1,113 +0,0 @@
|
||||
#pragma once
|
||||
#include <ircolib/types.hpp>
|
||||
#include <capstone/capstone.h>
|
||||
#include <xbyak/xbyak.h>
|
||||
#include <array>
|
||||
|
||||
namespace weee::core {
|
||||
struct mem;
|
||||
struct broadway {
|
||||
broadway();
|
||||
void set_pc(ircolib::u32);
|
||||
void run(mem &);
|
||||
|
||||
private:
|
||||
ircolib::u32 fetch(mem &);
|
||||
void print_disasm(ircolib::u32);
|
||||
void execute(ircolib::u32, mem &);
|
||||
|
||||
bool disasm_available = true;
|
||||
ircolib::u32 pc = 0, lr = 0, ctr = 0, cr = 0, srr0 = 0, fpscr = 0, msr = 0;
|
||||
union {
|
||||
struct {
|
||||
unsigned bytecount : 7;
|
||||
unsigned : 22;
|
||||
unsigned ca : 1;
|
||||
unsigned ov : 1;
|
||||
unsigned so : 1;
|
||||
};
|
||||
|
||||
ircolib::u32 raw;
|
||||
} xer;
|
||||
|
||||
void set_cr(ircolib::u8 value, ircolib::u8 index) {
|
||||
cr &= ~(0xffff << index * 4);
|
||||
cr |= (value << index * 4);
|
||||
}
|
||||
|
||||
bool get_cr_bit(ircolib::u8 index, ircolib::u8 bit) { return (cr >> index * 4) & (1 << (4 - bit)); }
|
||||
|
||||
// bat registers indexes
|
||||
static constexpr std::size_t BAT_LOWER_OFFSET = 0;
|
||||
static constexpr std::size_t BAT_UPPER_OFFSET = 8;
|
||||
|
||||
std::array<ircolib::u32, 16> ibat, dbat;
|
||||
std::array<ircolib::u32, 32> gpr{};
|
||||
|
||||
struct Fgr {
|
||||
ircolib::u64 ps0, ps1;
|
||||
};
|
||||
|
||||
std::array<Fgr, 32> fgrs{};
|
||||
|
||||
// ircolib::u32 const_gpr_lookup{};
|
||||
csh capstone;
|
||||
// Xbyak::CodeGenerator code;
|
||||
|
||||
// instructions
|
||||
void decode_special1(ircolib::u32, mem &);
|
||||
void decode_special2(ircolib::u32, mem &);
|
||||
void decode_special3(ircolib::u32, mem &);
|
||||
|
||||
void branch(bool, bool, ircolib::u32);
|
||||
bool test_cond_and_ctr(ircolib::u32);
|
||||
|
||||
void andi(ircolib::u32);
|
||||
void add(ircolib::u32);
|
||||
void addis(ircolib::u32);
|
||||
void addi(ircolib::u32);
|
||||
void ori(ircolib::u32);
|
||||
void oris(ircolib::u32);
|
||||
void bx(ircolib::u32);
|
||||
void bcx(ircolib::u32);
|
||||
void mftspr(bool, ircolib::u32);
|
||||
void stw(ircolib::u32, mem &);
|
||||
void stwu(ircolib::u32, mem &);
|
||||
void stbu(ircolib::u32, mem &);
|
||||
void sth(ircolib::u32, mem &);
|
||||
void lwz(ircolib::u32, mem &);
|
||||
void lfd(ircolib::u32, mem &);
|
||||
void bclrx(ircolib::u32);
|
||||
void cmpi(ircolib::u32);
|
||||
void cmpli(ircolib::u32);
|
||||
void cmp(ircolib::u32);
|
||||
void cmpl(ircolib::u32);
|
||||
void rlwinm(ircolib::u32);
|
||||
void lwzu(ircolib::u32, mem &);
|
||||
void rfi(ircolib::u32);
|
||||
void mtfsf(ircolib::u32);
|
||||
void mtfsb1(ircolib::u32);
|
||||
void mtfsb0(ircolib::u32);
|
||||
void mfmsr(ircolib::u32);
|
||||
void nand(ircolib::u32);
|
||||
void subf(ircolib::u32);
|
||||
void or (ircolib::u32);
|
||||
|
||||
inline void cr0_update(bool condition, ircolib::s32 result) {
|
||||
if (condition) {
|
||||
const bool b0 = result < 0;
|
||||
const bool b1 = result >= 0;
|
||||
const bool b2 = result == 0;
|
||||
const bool b3 = xer.so;
|
||||
set_cr((b0 << 3) | (b1 << 2) | (b2 << 1) | (b3 << 0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
inline void cr1_update(bool condition) {
|
||||
if (condition) {
|
||||
const ircolib::u8 field = (fpscr >> 28) & 0xf;
|
||||
set_cr(field, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace weee::core
|
||||
@@ -1,381 +0,0 @@
|
||||
#include "ircolib/log.hpp"
|
||||
#include <broadway/utils.hpp>
|
||||
#include <mem.hpp>
|
||||
|
||||
namespace weee::core {
|
||||
void broadway::add(ircolib::u32 instr) { gpr[utils::RD(instr)] = gpr[utils::RA(instr)] + gpr[utils::RB(instr)]; }
|
||||
|
||||
void broadway::addi(ircolib::u32 instr) {
|
||||
if (utils::RA(instr) == 0) { // lis
|
||||
gpr[utils::RD(instr)] = ircolib::s32(utils::SIMM(instr));
|
||||
return;
|
||||
}
|
||||
|
||||
gpr[utils::RD(instr)] = gpr[utils::RA(instr)] + (ircolib::s32(utils::SIMM(instr)));
|
||||
}
|
||||
|
||||
void broadway::addis(ircolib::u32 instr) {
|
||||
if (utils::RA(instr) == 0) { // lis
|
||||
gpr[utils::RD(instr)] = ircolib::s32(utils::SIMM(instr)) << 16;
|
||||
return;
|
||||
}
|
||||
|
||||
gpr[utils::RD(instr)] = gpr[utils::RA(instr)] + (ircolib::s32(utils::SIMM(instr)) << 16);
|
||||
}
|
||||
|
||||
void broadway::ori(ircolib::u32 instr) { gpr[utils::RA(instr)] = gpr[utils::RS(instr)] | utils::UIMM(instr); }
|
||||
void broadway::oris(ircolib::u32 instr) {
|
||||
gpr[utils::RA(instr)] = gpr[utils::RS(instr)] | ((ircolib::u32)utils::UIMM(instr) << 16);
|
||||
}
|
||||
|
||||
void broadway::branch(bool aa, bool lk, ircolib::u32 bd) {
|
||||
if (!aa)
|
||||
bd += pc - 4;
|
||||
|
||||
if (lk)
|
||||
lr = pc;
|
||||
|
||||
pc = bd;
|
||||
}
|
||||
|
||||
void broadway::bx(ircolib::u32 instr) {
|
||||
const bool link = instr & 1;
|
||||
const bool absolute = instr & 2;
|
||||
|
||||
ircolib::s32 li = (ircolib::s32(instr << 6) >> 6) & 0xFFFFFFFC;
|
||||
branch(absolute, link, li);
|
||||
}
|
||||
|
||||
bool broadway::test_cond_and_ctr(ircolib::u32 instr) {
|
||||
const ircolib::u8 bo = (instr >> 21) & 0x1f;
|
||||
const ircolib::u8 bi = (instr >> 16) & 0x1f;
|
||||
|
||||
const bool ctr_ok = ircolib::is_bit_set(bo, 2) || ((--ctr == 0) == (ircolib::is_bit_set(bo, 1)));
|
||||
const bool cond_ok = ircolib::is_bit_set(bo, 4) || (get_cr_bit(0, bi) == ircolib::is_bit_set(bo, 3));
|
||||
|
||||
return cond_ok && ctr_ok;
|
||||
}
|
||||
|
||||
void broadway::bcx(ircolib::u32 instr) {
|
||||
const bool link = instr & 1;
|
||||
const bool absolute = instr & 2;
|
||||
|
||||
ircolib::s32 bd = (ircolib::s32(instr << 16) >> 16) & 0xFFFFFFFC;
|
||||
if (test_cond_and_ctr(instr)) {
|
||||
branch(absolute, link, bd);
|
||||
}
|
||||
}
|
||||
|
||||
void broadway::mftspr(bool dir, ircolib::u32 instr) {
|
||||
const size_t spr_field = (instr >> 11) & 0x3FF;
|
||||
|
||||
auto move_to_or_from_spr = [&](ircolib::u32 &spr) {
|
||||
if (dir) { // mtspr
|
||||
spr = gpr[utils::RS(instr)];
|
||||
return;
|
||||
}
|
||||
// mfspr
|
||||
gpr[utils::RD(instr)] = spr;
|
||||
};
|
||||
|
||||
switch (spr_field) {
|
||||
case 0b0000100000:
|
||||
move_to_or_from_spr(xer.raw);
|
||||
break;
|
||||
case 0b0100000000:
|
||||
move_to_or_from_spr(lr);
|
||||
break;
|
||||
case 0b0100100000:
|
||||
move_to_or_from_spr(ctr);
|
||||
break;
|
||||
case 0b1101000000:
|
||||
move_to_or_from_spr(srr0);
|
||||
break;
|
||||
case 0b1101100000: // srr1
|
||||
break;
|
||||
case 0b1000011111: // hid0
|
||||
break;
|
||||
case 0b1100011100: // hid2
|
||||
break;
|
||||
case 0b1100111111: // l2cr
|
||||
break;
|
||||
case 0b1000110000:
|
||||
move_to_or_from_spr(ibat[BAT_LOWER_OFFSET + 0]);
|
||||
break;
|
||||
case 0b1000010000:
|
||||
move_to_or_from_spr(ibat[BAT_UPPER_OFFSET + 0]);
|
||||
break;
|
||||
case 0b1001010000:
|
||||
move_to_or_from_spr(ibat[BAT_UPPER_OFFSET + 1]);
|
||||
break;
|
||||
case 0b1010010000:
|
||||
move_to_or_from_spr(ibat[BAT_UPPER_OFFSET + 2]);
|
||||
break;
|
||||
case 0b1011010000:
|
||||
move_to_or_from_spr(ibat[BAT_UPPER_OFFSET + 3]);
|
||||
break;
|
||||
case 0b1100110000:
|
||||
move_to_or_from_spr(dbat[BAT_LOWER_OFFSET + 0]);
|
||||
break;
|
||||
case 0b1101110000:
|
||||
move_to_or_from_spr(dbat[BAT_LOWER_OFFSET + 1]);
|
||||
break;
|
||||
case 0b1100010000:
|
||||
move_to_or_from_spr(dbat[BAT_UPPER_OFFSET + 0]);
|
||||
break;
|
||||
case 0b1101010000:
|
||||
move_to_or_from_spr(dbat[BAT_UPPER_OFFSET + 1]);
|
||||
break;
|
||||
case 0b1110010000:
|
||||
move_to_or_from_spr(dbat[BAT_UPPER_OFFSET + 2]);
|
||||
break;
|
||||
case 0b1111010000:
|
||||
move_to_or_from_spr(dbat[BAT_UPPER_OFFSET + 3]);
|
||||
break;
|
||||
default:
|
||||
ircolib::warn("broadway::m{}spr with unimplemented spr field of value "
|
||||
"0b{:010b} (0x{:04X}) (pc 0x{:08X})",
|
||||
dir ? 't' : 'f', spr_field, spr_field, pc - 4);
|
||||
}
|
||||
}
|
||||
|
||||
void broadway::stwu(ircolib::u32 instr, mem &mem) {
|
||||
if (utils::RA(instr) == 0)
|
||||
ircolib::panic("broadway::stwu with ra == 0");
|
||||
|
||||
const ircolib::u32 EA = ircolib::s32(gpr[utils::RA(instr)]) + utils::SIMM(instr);
|
||||
auto _ = mem.write32(EA, gpr[utils::RS(instr)])
|
||||
.and_then([&] { return std::expected<void, std::string>(); })
|
||||
.or_else([&](std::string e) {
|
||||
ircolib::panic("stwu broadway write failed. Reason: {} (pc: 0x{:08X})", e, pc - 4);
|
||||
return std::expected<void, std::string>();
|
||||
});
|
||||
gpr[utils::RA(instr)] = EA;
|
||||
}
|
||||
|
||||
void broadway::stbu(ircolib::u32 instr, mem &mem) {
|
||||
if (utils::RA(instr) == 0)
|
||||
ircolib::panic("broadway::stbu with ra == 0");
|
||||
|
||||
const ircolib::u32 EA = ircolib::s32(gpr[utils::RA(instr)]) + utils::SIMM(instr);
|
||||
auto _ = mem.write8(EA, gpr[utils::RS(instr)])
|
||||
.and_then([&] { return std::expected<void, std::string>(); })
|
||||
.or_else([&](std::string e) {
|
||||
ircolib::panic("stbu broadway write failed. Reason: {} (pc: 0x{:08X})", e, pc - 4);
|
||||
return std::expected<void, std::string>();
|
||||
});
|
||||
gpr[utils::RA(instr)] = EA;
|
||||
}
|
||||
|
||||
void broadway::stw(ircolib::u32 instr, mem &mem) {
|
||||
ircolib::s32 b = gpr[utils::RA(instr)];
|
||||
if (utils::RA(instr) == 0)
|
||||
b = 0;
|
||||
|
||||
const ircolib::u32 EA = b + utils::SIMM(instr);
|
||||
auto _ = mem.write32(EA, gpr[utils::RS(instr)])
|
||||
.and_then([&] { return std::expected<void, std::string>(); })
|
||||
.or_else([&](std::string e) {
|
||||
ircolib::panic("stw broadway write failed. Reason: {} (pc: 0x{:08X})", e, pc - 4);
|
||||
return std::expected<void, std::string>();
|
||||
});
|
||||
}
|
||||
|
||||
void broadway::sth(ircolib::u32 instr, mem &mem) {
|
||||
ircolib::u32 b = gpr[utils::RA(instr)];
|
||||
if (utils::RA(instr) == 0)
|
||||
b = 0;
|
||||
|
||||
const ircolib::s32 d = utils::SIMM(instr);
|
||||
const ircolib::u32 EA = b + d;
|
||||
|
||||
auto _ = mem.write16(EA, ircolib::u16(gpr[utils::RS(instr)]))
|
||||
.and_then([&] { return std::expected<void, std::string>(); })
|
||||
.or_else([&](std::string e) {
|
||||
ircolib::panic("sth broadway write failed. Reason: {} (pc: 0x{:08X})", e, pc - 4);
|
||||
return std::expected<void, std::string>();
|
||||
});
|
||||
}
|
||||
|
||||
void broadway::lwz(ircolib::u32 instr, mem &mem) {
|
||||
ircolib::u32 b = gpr[utils::RA(instr)];
|
||||
if (utils::RA(instr) == 0)
|
||||
b = 0;
|
||||
|
||||
ircolib::u32 ea = ircolib::s32(b) + utils::SIMM(instr);
|
||||
|
||||
gpr[utils::RD(instr)] = mem.read32(ea)
|
||||
.and_then([&](ircolib::u32 val) { return std::expected<ircolib::u32, std::string>(val); })
|
||||
.or_else([&](std::string e) {
|
||||
ircolib::panic("broadway read failed. Reason {} (pc: 0x{:08X})", e, pc - 4);
|
||||
return std::expected<ircolib::u32, std::string>();
|
||||
})
|
||||
.value();
|
||||
}
|
||||
|
||||
void broadway::lfd(ircolib::u32 instr, mem &mem) {
|
||||
ircolib::u32 b = gpr[utils::RA(instr)];
|
||||
if (utils::RA(instr) == 0)
|
||||
b = 0;
|
||||
|
||||
ircolib::u32 ea = ircolib::s32(b) + utils::SIMM(instr);
|
||||
double val;
|
||||
ircolib::u64 read = mem.read64(ea)
|
||||
.and_then([&](ircolib::u64 val) { return std::expected<ircolib::u64, std::string>(val); })
|
||||
.or_else([&](std::string e) {
|
||||
ircolib::panic("broadway read failed. Reason {} (pc: 0x{:08X})", e, pc - 4);
|
||||
return std::expected<ircolib::u64, std::string>();
|
||||
})
|
||||
.value();
|
||||
memcpy(&val, &read, 8);
|
||||
fgrs[utils::RD(instr)].ps0 = val;
|
||||
}
|
||||
|
||||
void broadway::bclrx(ircolib::u32 instr) {
|
||||
const bool link = instr & 1;
|
||||
|
||||
ircolib::s32 bd = lr & 0xFFFFFFFC;
|
||||
if (test_cond_and_ctr(instr)) {
|
||||
branch(true, link, bd);
|
||||
}
|
||||
}
|
||||
|
||||
void broadway::cmpi(ircolib::u32 instr) {
|
||||
const ircolib::s32 a = gpr[utils::RA(instr)];
|
||||
const ircolib::s32 simm = utils::SIMM(instr);
|
||||
ircolib::u8 c;
|
||||
if (a < simm)
|
||||
c = 0b001;
|
||||
else if (a > simm)
|
||||
c = 0b010;
|
||||
else
|
||||
c = 0b100;
|
||||
|
||||
const ircolib::u8 result = (xer.so << 3) | c;
|
||||
set_cr(result, utils::crfD(instr));
|
||||
}
|
||||
|
||||
void broadway::cmpli(ircolib::u32 instr) {
|
||||
const ircolib::u32 a = gpr[utils::RA(instr)];
|
||||
const ircolib::u32 uimm = utils::UIMM(instr);
|
||||
ircolib::u8 c;
|
||||
if (a < uimm)
|
||||
c = 0b001;
|
||||
else if (a > uimm)
|
||||
c = 0b010;
|
||||
else
|
||||
c = 0b100;
|
||||
|
||||
const ircolib::u8 result = (xer.so << 3) | c;
|
||||
set_cr(result, utils::crfD(instr));
|
||||
}
|
||||
|
||||
void broadway::cmp(ircolib::u32 instr) {
|
||||
const ircolib::s32 a = gpr[utils::RA(instr)];
|
||||
const ircolib::s32 b = gpr[utils::RB(instr)];
|
||||
ircolib::u8 c;
|
||||
if (a < b)
|
||||
c = 0b001;
|
||||
else if (a > b)
|
||||
c = 0b010;
|
||||
else
|
||||
c = 0b100;
|
||||
|
||||
const ircolib::u8 result = (xer.so << 3) | c;
|
||||
set_cr(result, utils::crfD(instr));
|
||||
}
|
||||
|
||||
void broadway::cmpl(ircolib::u32 instr) {
|
||||
const ircolib::u32 a = gpr[utils::RA(instr)];
|
||||
const ircolib::u32 b = gpr[utils::RB(instr)];
|
||||
ircolib::u8 c;
|
||||
if (a < b)
|
||||
c = 0b001;
|
||||
else if (a > b)
|
||||
c = 0b010;
|
||||
else
|
||||
c = 0b100;
|
||||
|
||||
const ircolib::u8 result = (xer.so << 3) | c;
|
||||
set_cr(result, utils::crfD(instr));
|
||||
}
|
||||
|
||||
void broadway::rlwinm(ircolib::u32 instr) {
|
||||
const ircolib::u8 sh = (instr >> 11) & 0x1f;
|
||||
ircolib::u32 r = std::rotl(gpr[utils::RS(instr)], sh);
|
||||
const ircolib::u8 mb = (instr >> 6) & 0x1f;
|
||||
const ircolib::u8 me = (instr >> 1) & 0x1f;
|
||||
|
||||
r &= ~((0xFFFF'FFFF >> mb) << me);
|
||||
gpr[utils::RA(instr)] = r;
|
||||
}
|
||||
|
||||
void broadway::lwzu(ircolib::u32 instr, mem &mem) {
|
||||
if (utils::RA(instr) == 0 || utils::RA(instr) == utils::RD(instr))
|
||||
ircolib::panic("broadway::lwzu with ra == 0");
|
||||
|
||||
const ircolib::u32 EA = ircolib::s32(gpr[utils::RA(instr)]) + utils::SIMM(instr);
|
||||
gpr[utils::RD(instr)] = mem.read32(EA)
|
||||
.and_then([&](ircolib::u32 val) { return std::expected<ircolib::u32, std::string>(val); })
|
||||
.or_else([&](std::string e) {
|
||||
ircolib::panic("broadway read failed. Reason {} (pc: 0x{:08X})", e, pc - 4);
|
||||
return std::expected<ircolib::u32, std::string>();
|
||||
})
|
||||
.value();
|
||||
gpr[utils::RA(instr)] = EA;
|
||||
}
|
||||
|
||||
void broadway::rfi(ircolib::u32 instr) { pc = srr0; }
|
||||
|
||||
void broadway::andi(ircolib::u32 instr) {
|
||||
const ircolib::s32 result = gpr[utils::RS(instr)] & utils::UIMM(instr);
|
||||
gpr[utils::RA(instr)] = result;
|
||||
cr0_update(true, result);
|
||||
}
|
||||
|
||||
void broadway::mtfsf(ircolib::u32 instr) {
|
||||
const ircolib::u8 fm = (instr >> 17) & 0xff;
|
||||
ircolib::u8 mask = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (ircolib::is_bit_set(fm, i)) {
|
||||
mask |= 0xf << (i * 4);
|
||||
}
|
||||
}
|
||||
|
||||
ircolib::u32 frb = fgrs[utils::RB(instr)].ps0;
|
||||
fpscr = (fpscr & ~mask) | (frb & mask);
|
||||
cr1_update(instr & 1);
|
||||
}
|
||||
|
||||
void broadway::mtfsb0(ircolib::u32 instr) {
|
||||
ircolib::u32 mask = ~(1 << utils::RD(instr));
|
||||
|
||||
fpscr = fpscr & mask;
|
||||
cr1_update(instr & 1);
|
||||
}
|
||||
|
||||
void broadway::mtfsb1(ircolib::u32 instr) {
|
||||
ircolib::u32 bit = 1 << utils::RD(instr);
|
||||
ircolib::u32 mask = ~bit;
|
||||
|
||||
fpscr = (fpscr & mask) | bit;
|
||||
cr1_update(instr & 1);
|
||||
}
|
||||
|
||||
void broadway::mfmsr(ircolib::u32 instr) { gpr[utils::RS(instr)] = msr; }
|
||||
|
||||
void broadway::nand(ircolib::u32 instr) {
|
||||
gpr[utils::RA(instr)] = ~(gpr[utils::RS(instr)] & gpr[utils::RB(instr)]);
|
||||
cr0_update(instr & 1, gpr[utils::RA(instr)]);
|
||||
}
|
||||
|
||||
void broadway::subf(ircolib::u32 instr) {
|
||||
gpr[utils::RD(instr)] = ~(gpr[utils::RA(instr)] + gpr[utils::RB(instr)] + 1);
|
||||
cr0_update(instr & 1, gpr[utils::RD(instr)]);
|
||||
}
|
||||
|
||||
void broadway:: or (ircolib::u32 instr) {
|
||||
gpr[utils::RA(instr)] = gpr[utils::RS(instr)] & gpr[utils::RB(instr)];
|
||||
cr0_update(instr & 1, gpr[utils::RA(instr)]);
|
||||
}
|
||||
} // namespace weee::core
|
||||
@@ -1,78 +0,0 @@
|
||||
#include <broadway/mmio/vi.hpp>
|
||||
#include <ircolib/log.hpp>
|
||||
#include <mem.hpp>
|
||||
|
||||
namespace weee::core {
|
||||
video_interface::video_interface(mem &mem) {
|
||||
mem.register_write16_handler(0x0c002000, 0x0c0020ff,
|
||||
[&](ircolib::u32 addr, ircolib::u16 value) { write16(addr, value); });
|
||||
mem.register_write32_handler(0x0c002000, 0x0c0020ff,
|
||||
[&](ircolib::u32 addr, ircolib::u32 value) { write32(addr, value); });
|
||||
}
|
||||
|
||||
void video_interface::write16(ircolib::u32 addr, ircolib::u16 value) {
|
||||
switch (addr) {
|
||||
case 0x00:
|
||||
vtr.raw = value;
|
||||
break;
|
||||
case 0x02:
|
||||
dcr.raw = value;
|
||||
break;
|
||||
case 0x4a:
|
||||
hsr.raw = value;
|
||||
break;
|
||||
case 0x6c:
|
||||
viclk = value & 1;
|
||||
break;
|
||||
case 0x70:
|
||||
break;
|
||||
default:
|
||||
ircolib::panic("video_interface::write16 to unimplemented addr 0x{:04X} with value 0x{:04X}", addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
void video_interface::write32(ircolib::u32 addr, ircolib::u32 value) {
|
||||
switch (addr) {
|
||||
case 0x02:
|
||||
dcr.raw = value;
|
||||
break;
|
||||
case 0x04:
|
||||
htr0.raw = value;
|
||||
break;
|
||||
case 0x08:
|
||||
htr1.raw = value;
|
||||
break;
|
||||
case 0x0c:
|
||||
vto.raw = value;
|
||||
break;
|
||||
case 0x10:
|
||||
vte.raw = value;
|
||||
break;
|
||||
case 0x14:
|
||||
bbei.raw = value;
|
||||
break;
|
||||
case 0x18:
|
||||
bboi.raw = value;
|
||||
break;
|
||||
case 0x1c:
|
||||
tfbl.raw = value & 0x1ffffe00;
|
||||
break;
|
||||
case 0x24:
|
||||
bfbl.raw = value & 0x10fffe00;
|
||||
break;
|
||||
case 0x4c:
|
||||
case 0x50:
|
||||
case 0x54:
|
||||
fct0[addr - 0x4c].raw = value;
|
||||
break;
|
||||
case 0x58:
|
||||
case 0x5c:
|
||||
case 0x60:
|
||||
case 0x64:
|
||||
fct1[addr - 0x58].raw = value;
|
||||
break;
|
||||
default:
|
||||
ircolib::panic("video_interface::write32 to unimplemented addr 0x{:04X} with value 0x{:08X}", addr, value);
|
||||
}
|
||||
}
|
||||
} // namespace weee::core
|
||||
@@ -1,136 +0,0 @@
|
||||
#pragma once
|
||||
#include <ircolib/types.hpp>
|
||||
|
||||
namespace weee::core {
|
||||
struct mem;
|
||||
|
||||
struct video_interface {
|
||||
video_interface(mem &);
|
||||
void write16(ircolib::u32, ircolib::u16);
|
||||
void write32(ircolib::u32, ircolib::u32);
|
||||
ircolib::u32 xfb_top_addr() {
|
||||
auto addr = tfbl.fbb;
|
||||
if (tfbl.page) {
|
||||
addr <<= 5;
|
||||
}
|
||||
|
||||
return addr + tfbl.xof;
|
||||
}
|
||||
|
||||
union DCR {
|
||||
struct {
|
||||
unsigned e : 1;
|
||||
unsigned r : 1;
|
||||
unsigned i : 1;
|
||||
unsigned d : 1;
|
||||
unsigned le0 : 2;
|
||||
unsigned le1 : 2;
|
||||
unsigned fmt : 2;
|
||||
unsigned : 6;
|
||||
};
|
||||
|
||||
ircolib::u16 raw;
|
||||
} dcr;
|
||||
|
||||
union HTR0 {
|
||||
struct {
|
||||
unsigned hlw : 9;
|
||||
unsigned : 7;
|
||||
unsigned hce : 7;
|
||||
unsigned : 1;
|
||||
unsigned hcs : 7;
|
||||
unsigned : 1;
|
||||
};
|
||||
|
||||
ircolib::u32 raw;
|
||||
} htr0;
|
||||
|
||||
union HTR1 {
|
||||
struct {
|
||||
unsigned hsy : 7;
|
||||
unsigned hbe : 10;
|
||||
unsigned hbs : 10;
|
||||
unsigned : 5;
|
||||
};
|
||||
|
||||
ircolib::u32 raw;
|
||||
} htr1;
|
||||
|
||||
union VTR {
|
||||
struct {
|
||||
unsigned equ : 4;
|
||||
unsigned acv : 10;
|
||||
unsigned : 2;
|
||||
};
|
||||
|
||||
ircolib::u16 raw;
|
||||
} vtr;
|
||||
|
||||
union VTO {
|
||||
struct {
|
||||
unsigned prb : 10;
|
||||
unsigned : 6;
|
||||
unsigned psb : 10;
|
||||
unsigned : 6;
|
||||
};
|
||||
|
||||
ircolib::u32 raw;
|
||||
} vto, vte;
|
||||
|
||||
union BBI {
|
||||
struct {
|
||||
unsigned bs1 : 5;
|
||||
unsigned be1 : 11;
|
||||
unsigned bs3 : 5;
|
||||
unsigned be3 : 11;
|
||||
};
|
||||
|
||||
ircolib::u32 raw;
|
||||
} bbei, bboi;
|
||||
|
||||
union FBR {
|
||||
struct {
|
||||
unsigned : 3;
|
||||
unsigned page : 1;
|
||||
unsigned xof : 4;
|
||||
unsigned fbb : 24;
|
||||
};
|
||||
ircolib::u32 raw;
|
||||
} tfbl, bfbl;
|
||||
|
||||
union FCT012 {
|
||||
struct {
|
||||
unsigned tap0 : 10;
|
||||
unsigned tap1 : 10;
|
||||
unsigned tap2 : 10;
|
||||
unsigned : 2;
|
||||
};
|
||||
|
||||
ircolib::u32 raw;
|
||||
} fct0[3];
|
||||
|
||||
union FCT3456 {
|
||||
struct {
|
||||
unsigned tap0 : 8;
|
||||
unsigned tap1 : 8;
|
||||
unsigned tap2 : 8;
|
||||
unsigned tap3 : 8;
|
||||
};
|
||||
|
||||
ircolib::u32 raw;
|
||||
} fct1[4];
|
||||
|
||||
union HSR {
|
||||
struct {
|
||||
unsigned stp : 9;
|
||||
unsigned : 3;
|
||||
unsigned hs_en : 1;
|
||||
unsigned : 3;
|
||||
};
|
||||
|
||||
ircolib::u16 raw;
|
||||
} hsr;
|
||||
|
||||
bool viclk;
|
||||
};
|
||||
} // namespace weee::core
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
#include <broadway.hpp>
|
||||
|
||||
namespace weee::core::utils {
|
||||
static inline ircolib::u8 primary(ircolib::u32 instr) { return (instr >> 26) & 0x3f; }
|
||||
static inline ircolib::u16 secondary(ircolib::u32 instr) { return (instr >> 1) & 0x3ff; }
|
||||
static inline ircolib::u8 RD(ircolib::u32 instr) { return (instr >> 21) & 0x1f; }
|
||||
static inline ircolib::u8 RB(ircolib::u32 instr) { return (instr >> 11) & 0x1f; }
|
||||
static inline ircolib::u8 RS(ircolib::u32 instr) { return RD(instr); }
|
||||
static inline ircolib::u8 RA(ircolib::u32 instr) { return (instr >> 16) & 0x1f; }
|
||||
static inline ircolib::u16 UIMM(ircolib::u32 instr) { return instr & 0xffff; }
|
||||
static inline ircolib::s16 SIMM(ircolib::u32 instr) { return UIMM(instr); }
|
||||
static inline ircolib::u8 crfD(ircolib::u32 instr) { return (instr >> 23) & 7; }
|
||||
} // namespace weee::core::utils
|
||||
@@ -1,64 +0,0 @@
|
||||
#include <loaders/dol.hpp>
|
||||
#include <mem.hpp>
|
||||
#include <broadway.hpp>
|
||||
#include <ircolib/file.hpp>
|
||||
#include <ircolib/mem_access.hpp>
|
||||
#include <array>
|
||||
|
||||
namespace weee::core {
|
||||
bool load_dol(const std::string &path, mem &mem, broadway &broadway) {
|
||||
auto bin = ircolib::read_file_binary(path);
|
||||
if (bin.size() <= 0)
|
||||
return false;
|
||||
|
||||
struct header {
|
||||
struct section {
|
||||
ircolib::u32 offset, addr, size;
|
||||
};
|
||||
std::array<section, 7> text;
|
||||
std::array<section, 11> data;
|
||||
ircolib::u32 bss_address, bss_size, entry_point;
|
||||
} hdr;
|
||||
|
||||
for (size_t bin_index = 0; bin_index < 0xD8; bin_index += 4) {
|
||||
if (ircolib::is_inside_range(bin_index, 0, 0x1b)) // text file offsets
|
||||
hdr.text[bin_index / 4].offset = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
||||
|
||||
if (ircolib::is_inside_range(bin_index, 0x1c, 0x47)) // data file offsets
|
||||
hdr.data[(bin_index - 0x1c) / 4].offset = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
||||
|
||||
if (ircolib::is_inside_range(bin_index, 0x48, 0x63)) // text loading addresses
|
||||
hdr.text[(bin_index - 0x48) / 4].addr = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
||||
|
||||
if (ircolib::is_inside_range(bin_index, 0x64, 0x8f)) // data loading addresses
|
||||
hdr.data[(bin_index - 0x64) / 4].addr = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
||||
|
||||
if (ircolib::is_inside_range(bin_index, 0x90, 0xab)) // text sizes
|
||||
hdr.text[(bin_index - 0x90) / 4].size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
||||
|
||||
if (ircolib::is_inside_range(bin_index, 0xac, 0xd7)) // data sizes
|
||||
hdr.data[(bin_index - 0xac) / 4].size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, bin_index));
|
||||
}
|
||||
|
||||
hdr.bss_address = std::byteswap(ircolib::read_access<ircolib::u32>(bin, 0xD8));
|
||||
hdr.bss_size = std::byteswap(ircolib::read_access<ircolib::u32>(bin, 0xDC));
|
||||
mem.set(0, hdr.bss_size, hdr.bss_address & 0x0FFFFFFF);
|
||||
|
||||
hdr.entry_point = std::byteswap(ircolib::read_access<ircolib::u32>(bin, 0xE0));
|
||||
broadway.set_pc(hdr.entry_point);
|
||||
|
||||
for (const auto §ion : hdr.text) {
|
||||
if (section.offset == 0)
|
||||
continue;
|
||||
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
|
||||
}
|
||||
|
||||
for (const auto §ion : hdr.data) {
|
||||
if (section.offset == 0)
|
||||
continue;
|
||||
mem.copy(&bin[section.offset], section.size, section.addr & 0x0FFFFFFF);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace weee::core
|
||||
@@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
#include <ircolib/types.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace weee::core {
|
||||
struct mem;
|
||||
struct broadway;
|
||||
|
||||
bool load_dol(const std::string &, mem &, broadway &);
|
||||
} // namespace weee::core
|
||||
@@ -1,51 +0,0 @@
|
||||
#include <loaders/elf.hpp>
|
||||
#include <mem.hpp>
|
||||
#include <broadway.hpp>
|
||||
#include <elfio/elfio.hpp>
|
||||
#include <print>
|
||||
|
||||
namespace weee::core {
|
||||
bool load_elf(const std::string &path, mem &mem, broadway &broadway) {
|
||||
ELFIO::elfio reader;
|
||||
if (!reader.load(path))
|
||||
return false;
|
||||
|
||||
size_t sanity_bss_check_count = 0;
|
||||
|
||||
for (const auto &segment : reader.segments) {
|
||||
const auto segment_type = segment->get_type();
|
||||
if (segment_type != ELFIO::PT_LOAD && segment_type != ELFIO::PT_TLS && segment_type != ELFIO::PT_NOTE)
|
||||
continue;
|
||||
|
||||
if (segment->get_memory_size() == 0)
|
||||
continue;
|
||||
|
||||
const bool exc = segment->get_flags() & ELFIO::PF_X;
|
||||
const bool rd = segment->get_flags() & ELFIO::PF_R;
|
||||
const bool wr = segment->get_flags() & ELFIO::PF_W;
|
||||
|
||||
std::println("Segment {} {}{}{} @ 0x{:08X} -> 0x{:08X}", segment->get_index(), rd ? 'R' : '_', wr ? 'W' : '_',
|
||||
exc ? 'X' : '_', segment->get_virtual_address(),
|
||||
segment->get_virtual_address() + segment->get_memory_size() - 1);
|
||||
|
||||
if (segment->get_file_size() == 0) {
|
||||
sanity_bss_check_count++;
|
||||
if (sanity_bss_check_count > 1) {
|
||||
std::println("weee does not support multiple .bss segments");
|
||||
return -2;
|
||||
}
|
||||
|
||||
// .bss we zero out
|
||||
mem.set(0, segment->get_memory_size(), segment->get_virtual_address() & 0x0FFFFFFF);
|
||||
continue;
|
||||
}
|
||||
|
||||
mem.copy((ircolib::u8 *)segment->get_data(), segment->get_file_size(),
|
||||
segment->get_virtual_address() & 0x0FFFFFFF);
|
||||
}
|
||||
|
||||
broadway.set_pc(reader.get_entry());
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace weee::core
|
||||
@@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
#include <ircolib/types.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace weee::core {
|
||||
struct mem;
|
||||
struct broadway;
|
||||
|
||||
bool load_elf(const std::string &, mem &, broadway &);
|
||||
} // namespace weee::core
|
||||
@@ -1,151 +0,0 @@
|
||||
#include <cstring>
|
||||
#include <mem.hpp>
|
||||
#include <ircolib/log.hpp>
|
||||
#include "ircolib/mem_access.hpp"
|
||||
|
||||
namespace weee::core {
|
||||
mem::mem() : vi(*this) {
|
||||
mem1.resize(24_mib);
|
||||
std::fill(mem1.begin(), mem1.end(), 0);
|
||||
|
||||
register_read8_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr) { return mem1[addr]; });
|
||||
|
||||
register_read16_handler(0x00000000, 0x017fffff,
|
||||
[&](ircolib::u32 addr) { return ircolib::read_access<ircolib::u16>(mem1, addr); });
|
||||
|
||||
register_read32_handler(0x00000000, 0x017fffff,
|
||||
[&](ircolib::u32 addr) { return ircolib::read_access<ircolib::u32>(mem1, addr); });
|
||||
|
||||
register_read64_handler(0x00000000, 0x017fffff,
|
||||
[&](ircolib::u32 addr) { return ircolib::read_access<ircolib::u64>(mem1, addr); });
|
||||
|
||||
register_write8_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u8 value) { mem1[addr] = value; });
|
||||
|
||||
register_write16_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u16 value) {
|
||||
ircolib::write_access<ircolib::u16>(mem1, addr, value);
|
||||
});
|
||||
|
||||
register_write32_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u32 value) {
|
||||
ircolib::write_access<ircolib::u32>(mem1, addr, value);
|
||||
});
|
||||
|
||||
register_write64_handler(0x00000000, 0x017fffff, [&](ircolib::u32 addr, ircolib::u32 value) {
|
||||
ircolib::write_access<ircolib::u64>(mem1, addr, value);
|
||||
});
|
||||
}
|
||||
|
||||
void mem::copy(std::vector<ircolib::u8> &src, const ircolib::u32 offset) {
|
||||
if (offset + src.size() >= mem1.size())
|
||||
ircolib::panic("mem::copy outside mem1 range (src @ 0x{:08} for size 0x{:08X})", offset, src.size());
|
||||
|
||||
ircolib::swap_buffer<ircolib::u32>(src);
|
||||
std::copy(src.begin(), src.end(), mem1.begin() + offset);
|
||||
}
|
||||
|
||||
void mem::copy(ircolib::u8 *src, const ircolib::u32 size, const ircolib::u32 offset) {
|
||||
if (offset + size >= mem1.size())
|
||||
ircolib::panic("mem::copy outside mem1 range (src @ 0x{:08} for size 0x{:08X})", offset, size);
|
||||
|
||||
ircolib::swap_buffer<ircolib::u32>(src, size);
|
||||
memcpy(&mem1[offset], src, size);
|
||||
}
|
||||
|
||||
void mem::set(const ircolib::u8 val, const ircolib::u32 size, const ircolib::u32 offset) {
|
||||
if (offset + size >= mem1.size())
|
||||
ircolib::panic("mem::set outside mem1 range (@ 0x{:08} for size 0x{:08X})", offset, size);
|
||||
|
||||
memset(&mem1[offset], val, size);
|
||||
}
|
||||
|
||||
std::expected<ircolib::u8, std::string> mem::read8(ircolib::u32 addr) {
|
||||
addr &= 0x0FFFFFFF;
|
||||
for (const auto &handler : read8_handlers) {
|
||||
if (ircolib::is_inside_range(addr, handler.start, handler.end)) {
|
||||
return handler.func(addr - handler.start);
|
||||
}
|
||||
}
|
||||
|
||||
return std::unexpected(std::format("mem::read8 unimplemented addr 0x{:08X}", addr));
|
||||
}
|
||||
|
||||
std::expected<ircolib::u16, std::string> mem::read16(ircolib::u32 addr) {
|
||||
addr &= 0x0FFFFFFF;
|
||||
for (const auto &handler : read16_handlers) {
|
||||
if (ircolib::is_inside_range(addr, handler.start, handler.end)) {
|
||||
return handler.func(addr - handler.start);
|
||||
}
|
||||
}
|
||||
|
||||
return std::unexpected(std::format("mem::read16 unimplemented addr 0x{:08X}", addr));
|
||||
}
|
||||
|
||||
std::expected<ircolib::u32, std::string> mem::read32(ircolib::u32 addr) {
|
||||
addr &= 0x0FFFFFFF;
|
||||
for (const auto &handler : read32_handlers) {
|
||||
if (ircolib::is_inside_range(addr, handler.start, handler.end)) {
|
||||
return handler.func(addr - handler.start);
|
||||
}
|
||||
}
|
||||
|
||||
return std::unexpected(std::format("mem::read32 unimplemented addr 0x{:08X}", addr));
|
||||
}
|
||||
|
||||
std::expected<ircolib::u64, std::string> mem::read64(ircolib::u32 addr) {
|
||||
addr &= 0x0FFFFFFF;
|
||||
for (const auto &handler : read64_handlers) {
|
||||
if (ircolib::is_inside_range(addr, handler.start, handler.end)) {
|
||||
return handler.func(addr - handler.start);
|
||||
}
|
||||
}
|
||||
|
||||
return std::unexpected(std::format("mem::read64 unimplemented addr 0x{:08X}", addr));
|
||||
}
|
||||
|
||||
std::expected<void, std::string> mem::write8(ircolib::u32 addr, ircolib::u8 value) {
|
||||
addr &= 0x0FFFFFFF;
|
||||
for (const auto &handler : write8_handlers) {
|
||||
if (ircolib::is_inside_range(addr, handler.start, handler.end)) {
|
||||
handler.func(addr - handler.start, value);
|
||||
return std::expected<void, std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
return std::unexpected(std::format("mem::write8 unimplemented addr 0x{:08X} = 0x{:02X}", addr, value));
|
||||
}
|
||||
|
||||
std::expected<void, std::string> mem::write16(ircolib::u32 addr, ircolib::u16 value) {
|
||||
addr &= 0x0FFFFFFF;
|
||||
for (const auto &handler : write16_handlers) {
|
||||
if (ircolib::is_inside_range(addr, handler.start, handler.end)) {
|
||||
handler.func(addr - handler.start, value);
|
||||
return std::expected<void, std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
return std::unexpected(std::format("mem::write16 unimplemented addr 0x{:08X} = 0x{:04X}", addr, value));
|
||||
}
|
||||
|
||||
std::expected<void, std::string> mem::write32(ircolib::u32 addr, ircolib::u32 value) {
|
||||
addr &= 0x0FFFFFFF;
|
||||
for (const auto &handler : write32_handlers) {
|
||||
if (ircolib::is_inside_range(addr, handler.start, handler.end)) {
|
||||
handler.func(addr - handler.start, value);
|
||||
return std::expected<void, std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
return std::unexpected(std::format("mem::write32 unimplemented addr 0x{:08X} = 0x{:08X}", addr, value));
|
||||
}
|
||||
|
||||
std::expected<void, std::string> mem::write64(ircolib::u32 addr, ircolib::u64 value) {
|
||||
addr &= 0x0FFFFFFF;
|
||||
for (const auto &handler : write64_handlers) {
|
||||
if (ircolib::is_inside_range(addr, handler.start, handler.end)) {
|
||||
handler.func(addr - handler.start, value);
|
||||
return std::expected<void, std::string>();
|
||||
}
|
||||
}
|
||||
|
||||
return std::unexpected(std::format("mem::write64 unimplemented addr 0x{:08X} = 0x{:016X}", addr, value));
|
||||
}
|
||||
} // namespace weee::core
|
||||
@@ -1,86 +0,0 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <ircolib/types.hpp>
|
||||
#include <broadway/mmio/vi.hpp>
|
||||
#include <functional>
|
||||
#include <expected>
|
||||
|
||||
namespace weee::core {
|
||||
template <typename T>
|
||||
struct read_handler {
|
||||
std::function<T(ircolib::u32)> func;
|
||||
ircolib::u32 start, end;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct write_handler {
|
||||
std::function<void(ircolib::u32, T)> func;
|
||||
ircolib::u32 start, end;
|
||||
};
|
||||
|
||||
struct mem {
|
||||
mem();
|
||||
|
||||
void register_read8_handler(ircolib::u32 start, ircolib::u32 end,
|
||||
const std::function<ircolib::u8(ircolib::u32)> &func) {
|
||||
read8_handlers.push_back({std::move(func), start, end});
|
||||
}
|
||||
void register_read16_handler(ircolib::u32 start, ircolib::u32 end,
|
||||
const std::function<ircolib::u16(ircolib::u32)> &func) {
|
||||
read16_handlers.push_back({std::move(func), start, end});
|
||||
}
|
||||
void register_read32_handler(ircolib::u32 start, ircolib::u32 end,
|
||||
const std::function<ircolib::u32(ircolib::u32)> &func) {
|
||||
read32_handlers.push_back({std::move(func), start, end});
|
||||
}
|
||||
void register_read64_handler(ircolib::u32 start, ircolib::u32 end,
|
||||
const std::function<ircolib::u64(ircolib::u32)> &func) {
|
||||
read64_handlers.push_back({std::move(func), start, end});
|
||||
}
|
||||
void register_write8_handler(ircolib::u32 start, ircolib::u32 end,
|
||||
const std::function<void(ircolib::u32, ircolib::u8)> &func) {
|
||||
write8_handlers.push_back({std::move(func), start, end});
|
||||
}
|
||||
void register_write16_handler(ircolib::u32 start, ircolib::u32 end,
|
||||
const std::function<void(ircolib::u32, ircolib::u16)> &func) {
|
||||
write16_handlers.push_back({std::move(func), start, end});
|
||||
}
|
||||
void register_write32_handler(ircolib::u32 start, ircolib::u32 end,
|
||||
const std::function<void(ircolib::u32, ircolib::u32)> &func) {
|
||||
write32_handlers.push_back({std::move(func), start, end});
|
||||
}
|
||||
void register_write64_handler(ircolib::u32 start, ircolib::u32 end,
|
||||
const std::function<void(ircolib::u32, ircolib::u64)> &func) {
|
||||
write64_handlers.push_back({std::move(func), start, end});
|
||||
}
|
||||
|
||||
std::expected<ircolib::u8, std::string> read8(ircolib::u32);
|
||||
std::expected<ircolib::u16, std::string> read16(ircolib::u32);
|
||||
std::expected<ircolib::u32, std::string> read32(ircolib::u32);
|
||||
std::expected<ircolib::u64, std::string> read64(ircolib::u32);
|
||||
std::expected<void, std::string> write8(ircolib::u32, ircolib::u8);
|
||||
std::expected<void, std::string> write16(ircolib::u32, ircolib::u16);
|
||||
std::expected<void, std::string> write32(ircolib::u32, ircolib::u32);
|
||||
std::expected<void, std::string> write64(ircolib::u32, ircolib::u64);
|
||||
|
||||
void copy(std::vector<ircolib::u8> &src, const ircolib::u32 offset);
|
||||
void copy(ircolib::u8 *src, const ircolib::u32 size, const ircolib::u32 offset);
|
||||
void set(const ircolib::u8 val, const ircolib::u32 size, const ircolib::u32 offset);
|
||||
|
||||
std::vector<ircolib::u8> mem1;
|
||||
|
||||
private:
|
||||
std::vector<read_handler<ircolib::u8>> read8_handlers{};
|
||||
std::vector<read_handler<ircolib::u16>> read16_handlers{};
|
||||
std::vector<read_handler<ircolib::u32>> read32_handlers{};
|
||||
std::vector<read_handler<ircolib::u64>> read64_handlers{};
|
||||
std::vector<write_handler<ircolib::u8>> write8_handlers{};
|
||||
std::vector<write_handler<ircolib::u16>> write16_handlers{};
|
||||
std::vector<write_handler<ircolib::u32>> write32_handlers{};
|
||||
std::vector<write_handler<ircolib::u64>> write64_handlers{};
|
||||
|
||||
public:
|
||||
video_interface vi;
|
||||
};
|
||||
} // namespace weee::core
|
||||
@@ -1,34 +0,0 @@
|
||||
BasedOnStyle : LLVM
|
||||
|
||||
AccessModifierOffset : -2
|
||||
AlignAfterOpenBracket : true
|
||||
AlignConsecutiveAssignments : true
|
||||
AlignConsecutiveDeclarations : true
|
||||
AlignConsecutiveMacros : true
|
||||
AlignEscapedNewlines : true
|
||||
AlignOperands : true
|
||||
AlignTrailingComments : true
|
||||
BinPackParameters : false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel : true
|
||||
AfterClass : true
|
||||
AfterEnum : true
|
||||
AfterFunction : true
|
||||
AfterNamespace : false
|
||||
AfterStruct : true
|
||||
AfterExternBlock : true
|
||||
BeforeCatch : true
|
||||
BeforeElse : true
|
||||
BreakBeforeBraces : Custom
|
||||
ColumnLimit : 80
|
||||
FixNamespaceComments : true
|
||||
IndentCaseLabels : false
|
||||
IndentWidth : 4
|
||||
NamespaceIndentation : Inner
|
||||
PointerAlignment : Left
|
||||
ReflowComments : false
|
||||
SortIncludes : false
|
||||
SpacesInConditionalStatement : true
|
||||
SpacesInParentheses : true
|
||||
TabWidth : 4
|
||||
UseTab : Never
|
||||
@@ -1 +0,0 @@
|
||||
*.a binary
|
||||
@@ -1,99 +0,0 @@
|
||||
name: C/C++ CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: CMake Build & Test
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, ubuntu-22.04, windows-latest, windows-2022, macos-13, macos-15]
|
||||
build_type: [Release, Debug]
|
||||
cpp_compiler: [g++, clang++, cl]
|
||||
include:
|
||||
- os: windows-latest
|
||||
cpp_compiler: cl
|
||||
c_compiler: cl
|
||||
- os: windows-2022
|
||||
cpp_compiler: cl
|
||||
c_compiler: cl
|
||||
- os: ubuntu-latest
|
||||
cpp_compiler: g++
|
||||
c_compiler: gcc
|
||||
- os: ubuntu-latest
|
||||
cpp_compiler: clang++
|
||||
c_compiler: clang
|
||||
- os: ubuntu-22.04
|
||||
cpp_compiler: g++
|
||||
c_compiler: gcc
|
||||
- os: ubuntu-22.04
|
||||
cpp_compiler: clang++
|
||||
c_compiler: clang
|
||||
- os: macos-13
|
||||
cpp_compiler: g++
|
||||
c_compiler: gcc
|
||||
- os: macos-13
|
||||
cpp_compiler: clang++
|
||||
c_compiler: clang
|
||||
- os: macos-15
|
||||
cpp_compiler: g++
|
||||
c_compiler: gcc
|
||||
- os: macos-15
|
||||
cpp_compiler: clang++
|
||||
c_compiler: clang
|
||||
exclude:
|
||||
- os: windows-latest
|
||||
cpp_compiler: g++
|
||||
- os: windows-latest
|
||||
cpp_compiler: clang++
|
||||
- os: windows-2022
|
||||
cpp_compiler: g++
|
||||
- os: windows-2022
|
||||
cpp_compiler: clang++
|
||||
- os: ubuntu-latest
|
||||
cpp_compiler: cl
|
||||
- os: ubuntu-22.04
|
||||
cpp_compiler: cl
|
||||
- os: macos-13
|
||||
cpp_compiler: cl
|
||||
- os: macos-15
|
||||
cpp_compiler: cl
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'Serge1/ELFIO'
|
||||
|
||||
- name: Set reusable strings
|
||||
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
|
||||
id: strings
|
||||
shell: bash
|
||||
run: |
|
||||
echo "build-output-dir=${{ github.workspace }}/build/${{ matrix.build_type }}/${{ matrix.cpp_compiler }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Configure CMake
|
||||
run: >
|
||||
cmake -B ${{ steps.strings.outputs.build-output-dir }}
|
||||
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
|
||||
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||
-DELFIO_BUILD_EXAMPLES=YES -DELFIO_BUILD_TESTS=YES
|
||||
-S ${{ github.workspace }}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}
|
||||
|
||||
- name: Test
|
||||
working-directory: ${{ steps.strings.outputs.build-output-dir }}
|
||||
run: ctest --build-config ${{ matrix.build_type }} --output-on-failure --verbose
|
||||
@@ -1,69 +0,0 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [master]
|
||||
schedule:
|
||||
- cron: '0 15 * * 5'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
permissions:
|
||||
actions: read # for github/codeql-action/init to get workflow details
|
||||
contents: read # for actions/checkout to fetch code
|
||||
security-events: write # for github/codeql-action/analyze to upload SARIF results
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# Override automatic language detection by changing the below list
|
||||
# Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
|
||||
language: ['cpp']
|
||||
# Learn more...
|
||||
# https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
#- run: git checkout HEAD^2
|
||||
# if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
#- name: Autobuild
|
||||
# uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
- run: |
|
||||
cmake -B build -D ELFIO_BUILD_EXAMPLES=ON
|
||||
cmake --build build
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
@@ -1,100 +0,0 @@
|
||||
autom4te.cache
|
||||
Debug
|
||||
Release
|
||||
.vs
|
||||
tmp/
|
||||
docs
|
||||
|
||||
tests/Debug
|
||||
tests/Release
|
||||
tests/ELFIOTest
|
||||
tests/ELFIOTest.exe
|
||||
tests/runELFtests.trs
|
||||
|
||||
|
||||
examples/ELFDump/Debug
|
||||
examples/anonymizer/anonymizer
|
||||
examples/anonymizer/anonymizer.exe
|
||||
examples/elfdump/elfdump
|
||||
examples/elfdump/elfdump.exe
|
||||
examples/tutorial/tutorial
|
||||
examples/tutorial/tutorial.exe
|
||||
examples/write_obj/write_obj
|
||||
examples/write_obj/write_obj.exe
|
||||
examples/writer/writer
|
||||
examples/writer/writer.exe
|
||||
|
||||
|
||||
# generated elf files
|
||||
tests/elf_examples/*_copy
|
||||
tests/elf_examples/*_copy.elf
|
||||
tests/elf_examples/elf_dummy_header_i386_32.elf
|
||||
tests/elf_examples/elf_dummy_header_i386_64.elf
|
||||
tests/elf_examples/elf_dummy_header_ppc_32.elf
|
||||
tests/elf_examples/elf_dummy_header_ppc_64.elf
|
||||
tests/elf_examples/write_exe_i386_32
|
||||
tests/elf_examples/write_exe_i386_32_w_addr
|
||||
tests/elf_examples/write_exe_i386_32_wo_addr
|
||||
tests/elf_examples/write_exe_i386_32_section_added
|
||||
tests/elf_examples/ppc-32bit-testcopy*.elf
|
||||
tests/elf_examples/null_section_inside_segment*
|
||||
tests/elf_examples/segment_containing_no_section*
|
||||
tests/elf_examples/test_symbols_order.elf
|
||||
tests/elf_examples/zavl_gen.ko
|
||||
|
||||
tests/elfio_fuzzer
|
||||
tests/corpus
|
||||
|
||||
examples/writer/hello_x86_64
|
||||
examples/write_obj/hello
|
||||
examples/c_wrapper/c_example
|
||||
examples/add_section/add_section
|
||||
examples/elfdump/elfdump.trs
|
||||
|
||||
# various unwanted files (backups, objects, cmake artifacts)
|
||||
*~
|
||||
*.o
|
||||
*.kate-swp
|
||||
*.swp
|
||||
.#*
|
||||
\#*#
|
||||
CMakeCache.txt
|
||||
CMakeSettings.json
|
||||
Makefile
|
||||
CMakeFiles
|
||||
/build*/
|
||||
out
|
||||
*.res
|
||||
|
||||
# autotools artifacts
|
||||
.deps
|
||||
config.status
|
||||
ELFIOTest/runELFtests.trs
|
||||
|
||||
# eclipse project files
|
||||
.settings
|
||||
.project
|
||||
.cproject
|
||||
.cdtproject
|
||||
.cdtbuild
|
||||
|
||||
# netbeans project files
|
||||
/dist/
|
||||
Makefile
|
||||
.dep.inc
|
||||
nbproject
|
||||
|
||||
# QtCreator project files
|
||||
CMakeLists.txt.user
|
||||
|
||||
# ignore all _ prefixed directories (usually used for generated directories)
|
||||
_*/
|
||||
|
||||
# Latex build output
|
||||
*.pdf
|
||||
*.log
|
||||
*.out
|
||||
*.aux
|
||||
*.bbl
|
||||
*.toc
|
||||
*.blg
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}",
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/g++",
|
||||
"cStandard": "c11",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "clang-x64",
|
||||
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
|
||||
"configurationProvider": "ms-vscode.cmake-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Run ELFIO Tests",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/tests/ELFIOTest",
|
||||
"args": [
|
||||
//"--gtest_filter=ELFIOTest.load32",
|
||||
],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}/build/tests",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
//"preLaunchTask": "ELFIO Test build",
|
||||
"miDebuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
{
|
||||
"name": "Run ELFIO Tests (Windows)",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/tests/Debug/ELFIOTest.exe",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}/build/tests",
|
||||
"environment": [],
|
||||
"console": "externalTerminal"
|
||||
},
|
||||
{
|
||||
"name": "arioso (Windows)",
|
||||
"type": "cppvsdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/examples/arioso/Debug/arioso.exe",
|
||||
"args": ["${workspaceFolder}/build/tests/ario/simple_text.a", "-e", "hello.c", "-d", "hello.c", "-a", "hello.c"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}/build/examples/arioso",
|
||||
"environment": [],
|
||||
"console": "externalTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Run ELF Dump",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/examples/elfdump/elfdump",
|
||||
"args": ["build/tests/crash-de896e9e31bf6f4c540e7462ccc0440018e4f0de"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "ELF Dump Build",
|
||||
"miDebuggerPath": "/usr/bin/gdb"
|
||||
},
|
||||
{
|
||||
"name": "Run proc_mem",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/examples/proc_mem/proc_mem",
|
||||
"args": ["11706", "/usr/bin/bash"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"miDebuggerPath": "/home/user/ELFIO/examples/sudo_gdb.sh"
|
||||
},
|
||||
{
|
||||
"name": "Run dump for /proc/kcore",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/examples/elfdump/elfdump",
|
||||
"args": ["/proc/kcore"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"miDebuggerPath": "/home/user/ELFIO/examples/sudo_gdb.sh"
|
||||
},
|
||||
{
|
||||
"name": "Fuzzer",
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/tests/elfio_fuzzer",
|
||||
"args": ["crash-7143f5e49745dc6ce8909e642f9351d9d6496020"],
|
||||
"cwd": "${workspaceFolder}/build/tests"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"copyright": "json",
|
||||
"*.ipp": "cpp",
|
||||
"strstream": "cpp",
|
||||
"cerrno": "cpp",
|
||||
"csetjmp": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"rope": "cpp",
|
||||
"iostream": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"regex": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cassert": "cpp",
|
||||
"cctype": "cpp",
|
||||
"cfloat": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ciso646": "cpp",
|
||||
"climits": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"complex": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"locale": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"queue": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"thread": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"variant": "cpp",
|
||||
"compare": "cpp",
|
||||
"any": "cpp",
|
||||
"charconv": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"csignal": "cpp",
|
||||
"filesystem": "cpp",
|
||||
"format": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"mutex": "cpp",
|
||||
"span": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"xfacet": "cpp",
|
||||
"xhash": "cpp",
|
||||
"xiosbase": "cpp",
|
||||
"xlocale": "cpp",
|
||||
"xlocbuf": "cpp",
|
||||
"xlocinfo": "cpp",
|
||||
"xlocmes": "cpp",
|
||||
"xlocmon": "cpp",
|
||||
"xlocnum": "cpp",
|
||||
"xloctime": "cpp",
|
||||
"xmemory": "cpp",
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp"
|
||||
},
|
||||
"svn.ignoreMissingSvnWarning": true,
|
||||
"editor.tokenColorCustomizations": {
|
||||
"textMateRules": [
|
||||
{
|
||||
"scope": "googletest.failed",
|
||||
"settings": {
|
||||
"foreground": "#f00"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "googletest.passed",
|
||||
"settings": {
|
||||
"foreground": "#0f0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"scope": "googletest.run",
|
||||
"settings": {
|
||||
"foreground": "#0f0"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"gtest-adapter.debugConfig": "Run ELFIO Tests",
|
||||
"gtest-adapter.supportLocation": true,
|
||||
"sonarlint.pathToCompileCommands": "${workspaceFolder}/build/compile_commands.json"
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
{
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "ELFIO Test build",
|
||||
"command": "make",
|
||||
"args": ["INCLUDES=-I..", "CXXFLAGS='-g -O0'"],
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/build/tests"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": ["$gcc"]
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "ELF Dump Build",
|
||||
"command": "make",
|
||||
"args": ["INCLUDES=-I..", "CXXFLAGS='-g -O0'"],
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/build"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "clang-tidy",
|
||||
"command": "clang-tidy",
|
||||
"args": [
|
||||
"--checks=*,-modernize-use-trailing-return-type,-modernize-avoid-c-arrays,-llvm*,-fuchsia-*,-altera-*",
|
||||
"-header-filter=./*",
|
||||
"examples/elfdump/elfdump.cpp",
|
||||
"--",
|
||||
"-I."
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": ["$gcc"]
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Fuzzer",
|
||||
"command": "clang",
|
||||
"args": [
|
||||
"-g",
|
||||
"-O0",
|
||||
"-fsanitize=fuzzer,address",
|
||||
"-I..",
|
||||
"elfio_fuzzer.cpp",
|
||||
"-o",
|
||||
"elfio_fuzzer"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/tests"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": ["$gcc"]
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "Fuzzer Tests",
|
||||
"command": "./elfio_fuzzer",
|
||||
"args": ["-jobs=8", "corpus"],
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/tests"
|
||||
},
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": ["$gcc"]
|
||||
},
|
||||
{
|
||||
"type": "cmake",
|
||||
"label": "CMake: clean",
|
||||
"command": "clean",
|
||||
"problemMatcher": [],
|
||||
"detail": "CMake template clean task"
|
||||
},
|
||||
{
|
||||
"type": "cmake",
|
||||
"label": "CMake: clean rebuild",
|
||||
"command": "cleanRebuild",
|
||||
"targets": ["ALL_BUILD"],
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"detail": "CMake template clean rebuild task"
|
||||
}
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
# Detect if we are the top level CMakeLists.txt or are we included in some
|
||||
# other project
|
||||
if(NOT DEFINED PROJECT_NAME)
|
||||
set(IS_TOP_PROJECT TRUE)
|
||||
endif()
|
||||
|
||||
if(IS_TOP_PROJECT)
|
||||
# Turn this on in order to build elfio examples
|
||||
option(ELFIO_BUILD_EXAMPLES "Build ELFIO examples" ON)
|
||||
|
||||
# Turn this on in order to build tests
|
||||
option(ELFIO_BUILD_TESTS "Build ELFIO tests" OFF)
|
||||
|
||||
# Generate output of compile commands during generation
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
endif()
|
||||
|
||||
# Read version from header file
|
||||
set(version_header "elfio/elfio_version.hpp")
|
||||
file(READ ${version_header} ver)
|
||||
string(REGEX MATCH "#define ELFIO_VERSION \"([0-9\.]+)\"" _ ${ver})
|
||||
|
||||
if(NOT CMAKE_MATCH_1)
|
||||
message(FATAL_ERROR "Unable to parse version from ${version_header}")
|
||||
endif()
|
||||
|
||||
set(version ${CMAKE_MATCH_1})
|
||||
|
||||
# Use configure_file to make configure step depend on elfio_version.hpp
|
||||
configure_file(${version_header} ${CMAKE_CURRENT_BINARY_DIR}/elfio_version.hpp.copy COPYONLY)
|
||||
|
||||
project(elfio VERSION ${version} LANGUAGES C CXX)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
# Create a header only CMake target for elfio
|
||||
add_library(elfio INTERFACE)
|
||||
add_library(elfio::elfio ALIAS elfio)
|
||||
add_library(ario INTERFACE)
|
||||
add_library(ario::ario ALIAS ario)
|
||||
|
||||
target_include_directories(
|
||||
elfio
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
target_include_directories(
|
||||
ario
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
# If this is the top level project, add in logic to install elfio
|
||||
if(IS_TOP_PROJECT)
|
||||
# Enable C++17 for examples and tests
|
||||
if(ELFIO_BUILD_EXAMPLES OR ELFIO_BUILD_TESTS)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
endif()
|
||||
|
||||
if(ELFIO_BUILD_EXAMPLES)
|
||||
# set (CMAKE_CXX_FLAGS "-Wall")
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
if(ELFIO_BUILD_TESTS)
|
||||
# set (CMAKE_CXX_FLAGS "-Wall")
|
||||
enable_testing()
|
||||
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} USES_TERMINAL)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
# Create a file that includes the current project version. This will be
|
||||
# installed with the elfio CMake package.
|
||||
write_basic_package_version_file(
|
||||
"${PROJECT_NAME}ConfigVersion.cmake"
|
||||
VERSION
|
||||
${PROJECT_VERSION}
|
||||
COMPATIBILITY
|
||||
SameMajorVersion)
|
||||
|
||||
# Create the default ${PROJECT_NAME}Config.cmake file which will be
|
||||
# installed and found by calls to `find_package(elfio)`.
|
||||
configure_package_config_file(
|
||||
"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
|
||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
INSTALL_DESTINATION
|
||||
${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
|
||||
|
||||
# Install the previously generated "config" and "version" files
|
||||
install(
|
||||
FILES
|
||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
|
||||
|
||||
# Install the entire local `elfio` directory to the include directory
|
||||
install(
|
||||
DIRECTORY
|
||||
elfio
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
# Create a ${PROJECT_NAME}Targets.cmake file that is referenced by the
|
||||
# ${PROJECT_NAME}Config.cmake file and includes the target information
|
||||
# needed to compile/link against all targets exported under the
|
||||
# ${PROJECT_NAME}_Targets export
|
||||
install(
|
||||
EXPORT
|
||||
${PROJECT_NAME}_Targets
|
||||
FILE
|
||||
${PROJECT_NAME}Targets.cmake
|
||||
NAMESPACE
|
||||
${PROJECT_NAME}::
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
|
||||
|
||||
# Add the elfio target to the ${PROJECT_NAME}_Targets export
|
||||
install(
|
||||
TARGETS
|
||||
elfio
|
||||
EXPORT
|
||||
${PROJECT_NAME}_Targets)
|
||||
|
||||
# cmake -B build; cmake --build build; cpack --config build/CPackSourceConfig.cmake
|
||||
# cmake -B build -D ELFIO_BUILD_EXAMPLES=ON -DELFIO_BUILD_TESTS=ON -G Ninja; cmake --build build; cpack --config build/CPackSourceConfig.cmake
|
||||
set(_fmt TGZ)
|
||||
|
||||
if(WIN32)
|
||||
set(_fmt ZIP)
|
||||
endif()
|
||||
|
||||
set(CPACK_GENERATOR ${_fmt})
|
||||
set(CPACK_SOURCE_GENERATOR ${_fmt})
|
||||
set(CPACK_PACKAGE_VENDOR "ELFIO")
|
||||
set(CPACK_PACKAGE_CONTACT "Serge Lamikhov-Center")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt")
|
||||
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
|
||||
set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/package")
|
||||
set(CPACK_PACKAGE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
string(TOLOWER ${CMAKE_SYSTEM_NAME} _sys)
|
||||
string(TOLOWER ${PROJECT_NAME} _project_lower)
|
||||
set(CPACK_PACKAGE_FILE_NAME "${_project_lower}-${_sys}")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${_project_lower}-${PROJECT_VERSION}")
|
||||
|
||||
set(CPACK_SOURCE_IGNORE_FILES "/.git.*;/.vs.*;/build;/.clang-format;/doc/site;/doc/elfio.docx;/doc/images/callouts/;/doc/images/colorsvg/;/doc/images/res2/;/doc/images/.*\.svg;/doc/images/.*\.gif;/doc/images/[^/]*\.png$;/doc/images/.*\.tif;/examples/sudo_gdb.sh;/tests")
|
||||
|
||||
install(FILES ${CPACK_RESOURCE_FILE_README} ${CPACK_RESOURCE_FILE_LICENSE}
|
||||
DESTINATION share/docs/${PROJECT_NAME})
|
||||
|
||||
include(CPack)
|
||||
endif()
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -1,167 +0,0 @@
|
||||
<!--- # <img src="res/20231119165006-100.png" width="100"> ELFIO -->
|
||||
#  
|
||||
|
||||

|
||||

|
||||
[](http://elfio.sourceforge.net/elfio.pdf)
|
||||
[](https://github.com/serge1/ELFIO/blob/master/COPYING)
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [ELFIO: ELF Object and Executable File Reader/Writer](#elfio-elf-object-and-executable-file-readerwriter)
|
||||
- [ARIO: Advanced Archive Input/Output Library](#ario-advanced-archive-inputoutput-library)
|
||||
- [Who Uses ELFIO & ARIO?](#who-uses-elfio--ario)
|
||||
- [Installation](#installation)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Project Structure](#project-structure)
|
||||
- [Examples](#examples)
|
||||
- [Support](#support)
|
||||
- [Contributing](#contributing)
|
||||
- [License](#license)
|
||||
- [Resources](#resources)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
**ELFIO** and **ARIO** are robust, header-only C++ libraries designed to make binary file and archive manipulation effortless, efficient, and portable. Whether you are building compilers, linkers, binary analysis tools, or custom build systems, these libraries provide the foundation you need for working with ELF files and UNIX archives.
|
||||
|
||||
---
|
||||
|
||||
## ELFIO: ELF Object and Executable File Reader/Writer
|
||||
|
||||
**ELFIO** is a lightweight, header-only C++ library for reading and generating ELF (Executable and Linkable Format) binary files. It is completely standalone, requiring no external dependencies, and integrates seamlessly into any C++ project. Built to ISO C++ standards, ELFIO ensures compatibility across a wide range of architectures and compilers.
|
||||
|
||||
**Key Features:**
|
||||
|
||||
- **Header-only:** Just include the header files—no need to build or link external libraries.
|
||||
- **No dependencies:** Pure C++ implementation.
|
||||
- **Cross-platform:** Works on Windows, Linux, and macOS.
|
||||
- **Comprehensive ELF support:** Read, create, and modify ELF files, including sections, segments, and symbols.
|
||||
- **Easy integration:** Designed for both small utilities and large-scale applications.
|
||||
- **Actively maintained:** Trusted by open-source and commercial projects worldwide.
|
||||
|
||||
> 📖 Comprehensive documentation is available in the [ELFIO - Tutorial and User Manual (PDF)](http://elfio.sourceforge.net/elfio.pdf).
|
||||
|
||||
---
|
||||
|
||||
## ARIO: Advanced Archive Input/Output Library
|
||||
|
||||
**ARIO** is a modern, high-performance, header-only C++ library for reading, creating, and modifying UNIX `ar` archive files (commonly used for static libraries). ARIO is designed to work seamlessly with ELFIO, providing a unified and intuitive interface for archive manipulation and binary data management.
|
||||
|
||||
**Why Choose ARIO?**
|
||||
|
||||
- **Header-only:** Effortless integration—just include `ario.hpp` in your project.
|
||||
- **Zero dependencies:** No need for external libraries or build steps.
|
||||
- **Universal access:** Read and write to files, memory, and custom streams.
|
||||
- **Cross-platform:** Consistent behavior on Windows, Linux, and macOS.
|
||||
- **Optimized for performance:** Minimal overhead for high-throughput applications.
|
||||
- **Seamless ELFIO integration:** Easily combine ELF and archive operations in your toolchain.
|
||||
- **Intuitive API:** Designed for productivity and ease of use.
|
||||
|
||||
**Typical Use Cases:**
|
||||
|
||||
- Building and modifying static libraries (`.a` files)
|
||||
- Extracting or replacing object files within archives
|
||||
- Analyzing and manipulating symbol tables in archives
|
||||
- Custom build tools and binary utilities
|
||||
- Automated toolchains and CI/CD systems
|
||||
|
||||
---
|
||||
|
||||
## Who Uses ELFIO & ARIO?
|
||||
|
||||
- Open-source projects
|
||||
- Commercial toolchains
|
||||
- Academic research
|
||||
- Embedded systems
|
||||
- Binary analysis and reverse engineering tools
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
Simply copy the `elfio` and/or `ario` directories into your project and include the relevant headers. No build or linking steps are required.
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. **Add the header files** to your project:
|
||||
- For ELFIO: `#include <elfio/elfio.hpp>`
|
||||
- For ARIO: `#include <ario/ario.hpp>`
|
||||
|
||||
2. **No build steps required:** Both libraries are header-only.
|
||||
|
||||
3. **Example: Reading an ELF file**
|
||||
|
||||
```cpp
|
||||
#include <elfio/elfio.hpp>
|
||||
ELFIO::elfio reader;
|
||||
if (reader.load("my_binary.elf")) {
|
||||
// Access ELF sections, segments, symbols, etc.
|
||||
}
|
||||
```
|
||||
|
||||
4. **Example: Reading an archive file**
|
||||
|
||||
```cpp
|
||||
#include <ario/ario.hpp>
|
||||
ARIO::ario archive;
|
||||
if (archive.load("libmylib.a").ok()) {
|
||||
for (const auto& member : archive.members) {
|
||||
std::cout << "Member: " << member.name << std::endl;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
- `elfio/` — ELFIO header files
|
||||
- `ario/` — ARIO header files
|
||||
- `examples/` — Example usage and sample tools
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
The `examples/` directory contains a collection of sample programs demonstrating how to use ELFIO and ARIO in real-world scenarios. Each example focuses on a specific use case, such as reading and modifying ELF files, manipulating archive files, or integrating with C code. These examples serve both as practical tutorials and as a starting point for your own tools and applications.
|
||||
|
||||
**Purpose:**
|
||||
|
||||
- Illustrate typical usage patterns for ELFIO and ARIO
|
||||
- Provide ready-to-use code for common binary and archive operations
|
||||
- Help users quickly get started and understand library capabilities
|
||||
|
||||
Explore the `examples/` subdirectories for detailed demonstrations, including adding sections to ELF files, anonymizing binaries, working with archives, and more.
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
For questions or support, please open an issue on [GitHub](https://github.com/serge1/ELFIO/issues).
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions, bug reports, and feature requests are welcome! Please open an issue or submit a pull request on [GitHub](https://github.com/serge1/ELFIO).
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the [MIT License](https://github.com/serge1/ELFIO/blob/main/LICENSE.txt).
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- [ELFIO Documentation (PDF)](http://elfio.sourceforge.net/elfio.pdf)
|
||||
- [ELFIO on GitHub](https://github.com/serge1/ELFIO)
|
||||
- [ELF Specification](https://refspecs.linuxbase.org/elf/elf.pdf)
|
||||
@@ -1,930 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
//! @file ario.hpp
|
||||
//! @brief ARIO - Simple ar(1) archive reader/writer interface
|
||||
//!
|
||||
//! This file provides the ARIO namespace and the ario class for reading and manipulating UNIX ar archives.
|
||||
//!
|
||||
//! Copyright (C) 2025-present by Serge Lamikhov-Center
|
||||
//!
|
||||
//! Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
//! of this software and associated documentation files (the "Software"), to deal
|
||||
//! in the Software without restriction, including without limitation the rights
|
||||
//! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
//! copies of the Software, and to permit persons to whom the Software is
|
||||
//! furnished to do so, subject to the following conditions:
|
||||
//!
|
||||
//! The above copyright notice and this permission notice shall be included in
|
||||
//! all copies or substantial portions of the Software.
|
||||
//!
|
||||
//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
//! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
//! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
//! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
//! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
//! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
//! THE SOFTWARE.
|
||||
|
||||
#ifndef ARIO_HPP
|
||||
#define ARIO_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
namespace ARIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @class ario
|
||||
//! @brief Class for reading and manipulating ar(1) archives
|
||||
class ario
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Error structure for ARIO operations
|
||||
class Result
|
||||
{
|
||||
public:
|
||||
Result() = default;
|
||||
Result( const std::string& msg ) : message( msg ) {}
|
||||
Result( std::string&& msg ) : message( std::move( msg ) ) {}
|
||||
|
||||
bool ok() const { return !message.has_value(); }
|
||||
std::string what() const { return message.value_or( "No errors" ); }
|
||||
|
||||
private:
|
||||
std::optional<std::string> message; ///< Error message, if any
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @struct Member
|
||||
//! @brief Represents a single member (file) in the archive
|
||||
class Member
|
||||
{
|
||||
public:
|
||||
std::string name = {}; ///< Name of the member
|
||||
int date = {}; ///< Date of the member
|
||||
int uid = {}; ///< User ID of the member
|
||||
int gid = {}; ///< Group ID of the member
|
||||
int mode = {}; ///< Mode of the member
|
||||
size_t size = {}; ///< Size of the member in the archive
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get the data of the member as a string
|
||||
//! @return The data of the member
|
||||
std::string data() const
|
||||
{
|
||||
if ( new_data.has_value() ) {
|
||||
return new_data.value();
|
||||
}
|
||||
|
||||
if ( !pstream ) {
|
||||
return { "No input stream available for member data" };
|
||||
}
|
||||
|
||||
std::string data( size, '\0' );
|
||||
std::streamoff current_pos = pstream->tellg();
|
||||
pstream->seekg( filepos + HEADER_SIZE, std::ios::beg );
|
||||
if ( pstream->fail() ) {
|
||||
return { "Failed to seek to member data position" };
|
||||
}
|
||||
pstream->read( &data[0], size );
|
||||
if ( pstream->fail() || (size_t)pstream->gcount() < size ) {
|
||||
return { "Failed to read member data" };
|
||||
}
|
||||
|
||||
// Reset the stream position
|
||||
pstream->clear();
|
||||
pstream->seekg( current_pos, std::ios::beg );
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
operator std::string() const { return name; }
|
||||
operator std::string_view() const { return name; }
|
||||
operator const char*() const { return name.c_str(); }
|
||||
bool operator==( std::string_view name ) const
|
||||
{
|
||||
return this->name == name;
|
||||
}
|
||||
|
||||
protected:
|
||||
void set_input_stream( std::shared_ptr<std::istream>& pstream )
|
||||
{
|
||||
this->pstream = pstream;
|
||||
}
|
||||
|
||||
void set_new_data( std::string_view data ) { this->new_data = data; }
|
||||
|
||||
protected:
|
||||
std::string short_name = {}; ///< Short name of the member
|
||||
std::shared_ptr<std::istream> pstream =
|
||||
nullptr; ///< Pointer to the input stream
|
||||
std::streamoff filepos = {}; ///< File position in the archive
|
||||
std::optional<std::string> new_data = {};
|
||||
|
||||
friend class ario;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @class Members
|
||||
//! @brief Provides access to the members of the archive
|
||||
class Members
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Constructor
|
||||
//! @param parent Pointer to the parent ario object
|
||||
explicit Members( ario* parent ) : parent( parent ) {}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get the number of members
|
||||
//! @return The number of members
|
||||
size_t size() const { return parent->members_.size(); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get a member by index
|
||||
//! @param index The index of the member
|
||||
//! @return Reference to the member
|
||||
const Member& operator[]( size_t index ) const
|
||||
{
|
||||
if ( index >= parent->members_.size() ) {
|
||||
throw std::out_of_range( "Member index out of range" );
|
||||
}
|
||||
return parent->members_[index];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get a member by name
|
||||
//! @param name The name of the member
|
||||
//! @return Reference to the member, throws if not found
|
||||
const Member& operator[]( std::string_view name ) const
|
||||
{
|
||||
for ( const auto& m : parent->members_ ) {
|
||||
if ( m == name ) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
throw std::out_of_range( std::string( "Member not found: " ) +
|
||||
std::string( name ) );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get an iterator to the beginning of the members
|
||||
//! @return Iterator to the beginning of the members
|
||||
std::vector<Member>::iterator begin()
|
||||
{
|
||||
return parent->members_.begin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get an iterator to the end of the members
|
||||
//! @return Iterator to the end of the members
|
||||
std::vector<Member>::iterator end() { return parent->members_.end(); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get a const iterator to the beginning of the members
|
||||
//! @return Const iterator to the beginning of the members
|
||||
std::vector<Member>::const_iterator begin() const
|
||||
{
|
||||
return parent->members_.cbegin();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get a const iterator to the end of the members
|
||||
//! @return Const iterator to the end of the members
|
||||
std::vector<Member>::const_iterator end() const
|
||||
{
|
||||
return parent->members_.cend();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get a const reference to the first member
|
||||
//! @return Const reference to the first member
|
||||
const Member& front() const
|
||||
{
|
||||
if ( parent->members_.empty() ) {
|
||||
throw std::out_of_range( "No members in archive" );
|
||||
}
|
||||
return parent->members_.front();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get a const reference to the last member
|
||||
//! @return Const reference to the last member
|
||||
const Member& back() const
|
||||
{
|
||||
if ( parent->members_.empty() ) {
|
||||
throw std::out_of_range( "No members in archive" );
|
||||
}
|
||||
return parent->members_.back();
|
||||
}
|
||||
|
||||
private:
|
||||
ario* parent; //!< Pointer to the parent ario object
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Constructor
|
||||
explicit ario() : members( this ) {};
|
||||
ario( const ario& ) = delete;
|
||||
ario& operator=( const ario& ) = delete;
|
||||
ario( ario&& ) = delete;
|
||||
ario& operator=( ario&& ) = delete;
|
||||
~ario() = default;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Load an archive from a file
|
||||
//! @param file_name The name of the archive file
|
||||
//! @return Error object indicating success or failure
|
||||
Result load( const std::string& file_name )
|
||||
{
|
||||
auto ifs = std::make_unique<std::ifstream>();
|
||||
if ( !ifs ) {
|
||||
return { "Failed to create input stream" };
|
||||
}
|
||||
|
||||
ifs->open( file_name.c_str(), std::ios::in | std::ios::binary );
|
||||
if ( !*ifs ) {
|
||||
return { "Failed to open file: " + file_name };
|
||||
}
|
||||
|
||||
auto result = load( std::move( ifs ) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Load an archive from a stream
|
||||
//! @param stream The input stream to load from
|
||||
//! @return Error object indicating success or failure
|
||||
Result load( std::unique_ptr<std::istream> is )
|
||||
{
|
||||
if ( !is ) {
|
||||
return { "Input stream is null" };
|
||||
}
|
||||
|
||||
pstream = std::move( is );
|
||||
if ( !*pstream ) {
|
||||
return { "Failed to set input stream" };
|
||||
}
|
||||
|
||||
members_.clear();
|
||||
|
||||
auto result = load_header();
|
||||
if ( !result.ok() ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = load_members();
|
||||
if ( !result.ok() ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Save an archive to a file
|
||||
//! @param file_name The name of the archive file
|
||||
//! @return Error object indicating success or failure
|
||||
Result save( const std::string& file_name )
|
||||
{
|
||||
std::ofstream ofs;
|
||||
|
||||
ofs.open( file_name.c_str(), std::ios::out | std::ios::binary );
|
||||
if ( !ofs ) {
|
||||
return { "Failed to open file: " + file_name };
|
||||
}
|
||||
|
||||
auto result = save( ofs );
|
||||
|
||||
ofs.close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Save an archive to a stream
|
||||
//! @param stream The output stream to save to
|
||||
//! @return Error object indicating success or failure
|
||||
Result save( std::ostream& os )
|
||||
{
|
||||
if ( !os ) {
|
||||
return { "Output stream is null" };
|
||||
}
|
||||
|
||||
os.clear();
|
||||
os.seekp( 0, std::ios::beg );
|
||||
auto result = save_header( os );
|
||||
if ( !result.ok() ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Save symbol table if it exists
|
||||
if ( !symbol_table.empty() ) {
|
||||
result = save_symbol_table( os );
|
||||
if ( !result.ok() ) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Save long name directory if it exists
|
||||
if ( !string_table.empty() ) {
|
||||
result = save_long_name_directory( os );
|
||||
if ( !result.ok() ) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = save_members( os );
|
||||
if ( !result.ok() ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//! @brief Find a symbol in the archive
|
||||
//! @param name The name of the symbol to find
|
||||
//! @param out_member Pointer to store the found member
|
||||
//! @param member Reference to store the found member
|
||||
//! @return Error object indicating success or failure
|
||||
//! If the symbol is found, out_member will point to the corresponding member
|
||||
//! If the symbol is not found, out_member will stay unchanged
|
||||
Result
|
||||
find_symbol( std::string_view name,
|
||||
std::optional<std::reference_wrapper<const ario::Member>>&
|
||||
member ) const
|
||||
{
|
||||
const auto it = symbol_table.find( std::string( name ) );
|
||||
if ( it != symbol_table.end() ) {
|
||||
member = members_[it->second];
|
||||
return {};
|
||||
}
|
||||
member = std::nullopt;
|
||||
return { std::string( "Symbol not found: " ) + std::string( name ) };
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Get symbols for a specific member
|
||||
//! @param m Pointer to the member
|
||||
//! @param symbols Vector to store the found symbols
|
||||
//! @return Error object indicating success or failure
|
||||
//! If the member is found, symbols will contain the associated symbols
|
||||
//! If the member is not found, symbols will be empty
|
||||
Result get_symbols_for_member( const ario::Member& member,
|
||||
std::vector<std::string>& symbols ) const
|
||||
{
|
||||
std::string_view member_name = member.name;
|
||||
size_t index = std::distance(
|
||||
members.begin(),
|
||||
std::find_if(
|
||||
members.begin(), members.end(), [&]( const auto& mem ) {
|
||||
return std::string_view( mem.name ) == member_name;
|
||||
} ) );
|
||||
if ( index >= members.size() ) {
|
||||
return { "Member not found in archive" };
|
||||
}
|
||||
|
||||
symbols.clear();
|
||||
for ( const auto& symbol : symbol_table ) {
|
||||
if ( symbol.second == index ) {
|
||||
symbols.emplace_back( symbol.first );
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Add a member to the archive
|
||||
//! @param member The member to add
|
||||
//! @param data The data associated with the member
|
||||
//! @return Error object indicating success or failure
|
||||
Result add_member( const Member& member, std::string_view data )
|
||||
{
|
||||
// Don't allow empty member names
|
||||
if ( member.name.empty() ) {
|
||||
return { "Member name cannot be empty" };
|
||||
}
|
||||
|
||||
// Check if the member with such name already exists
|
||||
for ( const auto& mem : members_ ) {
|
||||
if ( mem.name == member.name ) {
|
||||
return { "Member '" + member.name + "' already exists" };
|
||||
}
|
||||
}
|
||||
|
||||
auto& new_member = members_.emplace_back( member );
|
||||
new_member.size = data.size();
|
||||
new_member.pstream = nullptr;
|
||||
new_member.set_new_data( data );
|
||||
|
||||
if ( member.name.size() < FIELD_NAME_SIZE ) {
|
||||
new_member.short_name = member.name + "/";
|
||||
}
|
||||
else {
|
||||
auto location = string_table.size();
|
||||
string_table += member.name + "/\x0A";
|
||||
new_member.short_name = "/" + std::to_string( location );
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Add symbols for a member
|
||||
//! @param member The member to add symbols for
|
||||
//! @param symbols The symbols to add
|
||||
//! @return Error object indicating success or failure
|
||||
Result add_symbols_for_member( const ario::Member& member,
|
||||
const std::vector<std::string>& symbols )
|
||||
{
|
||||
std::string_view member_name = member.name;
|
||||
size_t index = std::distance(
|
||||
members.begin(),
|
||||
std::find_if(
|
||||
members.begin(), members.end(), [&]( const auto& mem ) {
|
||||
return std::string_view( mem.name ) == member_name;
|
||||
} ) );
|
||||
if ( index >= members.size() ) {
|
||||
return { "Member not found in archive" };
|
||||
}
|
||||
|
||||
for ( const auto& symbol : symbols ) {
|
||||
symbol_table[symbol] = index;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Load the archive header
|
||||
//! @param in Input file stream
|
||||
//! @return Error object indicating success or failure
|
||||
Result load_header()
|
||||
{
|
||||
auto arch_magic = std::string( ARCH_MAGIC );
|
||||
auto arch_magic_size = arch_magic.size();
|
||||
std::string magic( arch_magic_size, ' ' );
|
||||
pstream->read( &magic[0], arch_magic_size );
|
||||
if ( magic != arch_magic ) {
|
||||
return { std::string( "Invalid archive format. Expected magic: " ) +
|
||||
arch_magic + ", but got " + magic };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Load all members from the archive
|
||||
//! @param in Input file stream
|
||||
//! @return Error object indicating success or failure
|
||||
Result load_members()
|
||||
{
|
||||
while ( true ) {
|
||||
Member m;
|
||||
m.set_input_stream( pstream );
|
||||
|
||||
char header[HEADER_SIZE];
|
||||
auto filepos = pstream->tellg();
|
||||
|
||||
pstream->read( header, HEADER_SIZE );
|
||||
if ( pstream->gcount() < HEADER_SIZE ) {
|
||||
if ( pstream->gcount() > 0 ) {
|
||||
return { "Corrupted archive" }; // End of file or error
|
||||
}
|
||||
break; // End of file reached
|
||||
}
|
||||
std::streamoff current_pos = pstream->tellg();
|
||||
m.short_name = std::string( header, FIELD_NAME_SIZE );
|
||||
m.name = m.short_name;
|
||||
m.filepos = filepos;
|
||||
|
||||
std::string date_str( header + FIELD_NAME_SIZE, FIELD_DATE_SIZE );
|
||||
std::string uid_str( header + FIELD_NAME_SIZE + FIELD_DATE_SIZE,
|
||||
FIELD_UID_SIZE );
|
||||
std::string gid_str( header + +FIELD_NAME_SIZE + FIELD_DATE_SIZE +
|
||||
FIELD_UID_SIZE,
|
||||
FIELD_GID_SIZE );
|
||||
std::string mode_str( header + FIELD_NAME_SIZE + FIELD_DATE_SIZE +
|
||||
FIELD_UID_SIZE + FIELD_GID_SIZE,
|
||||
FIELD_MODE_SIZE );
|
||||
std::string size_str( header + FIELD_NAME_SIZE + FIELD_DATE_SIZE +
|
||||
FIELD_UID_SIZE + FIELD_GID_SIZE +
|
||||
FIELD_MODE_SIZE,
|
||||
FIELD_SIZE_SIZE );
|
||||
|
||||
try {
|
||||
// Get m.size from the header. Do it earlier due to the potential use of m.data()
|
||||
// It is the only valid field in special members like symbol table and long name directory
|
||||
m.size = std::stoi( size_str );
|
||||
}
|
||||
catch ( const std::exception& ) {
|
||||
return { "Invalid member size" };
|
||||
}
|
||||
|
||||
if ( m.short_name ==
|
||||
"/ " ) { // Special case for the symbol table
|
||||
m.name = "/";
|
||||
auto result = load_symbol_table();
|
||||
if ( !result.ok() ) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (
|
||||
m.short_name ==
|
||||
"// " ) { // Special case for the long name directory
|
||||
m.name = "//";
|
||||
string_table = m.data(); // Read the long name directory data
|
||||
}
|
||||
else {
|
||||
try {
|
||||
m.date = std::stoi( date_str );
|
||||
m.uid = std::stoi( uid_str );
|
||||
m.gid = std::stoi( gid_str );
|
||||
m.mode = std::stoi( mode_str, nullptr, FIELD_MODE_SIZE );
|
||||
}
|
||||
catch ( const std::exception& ) {
|
||||
return { "Invalid member header's field: " + m.short_name +
|
||||
", " + date_str + ", " + uid_str + ", " + gid_str +
|
||||
", " + mode_str };
|
||||
}
|
||||
|
||||
if ( m.short_name[0] == '/' ) {
|
||||
auto name_result = convert_name( m.short_name );
|
||||
if ( !name_result.has_value() ) {
|
||||
return { "Failed to convert long name for member " +
|
||||
m.short_name };
|
||||
}
|
||||
m.name = *name_result;
|
||||
}
|
||||
else {
|
||||
m.name = m.short_name.substr( 0, m.short_name.find( '/' ) );
|
||||
}
|
||||
|
||||
// Add only the regular member to the list
|
||||
members_.emplace_back( m );
|
||||
}
|
||||
|
||||
// Skip the content of the member
|
||||
pstream->clear();
|
||||
pstream->seekg( current_pos + m.size + m.size % 2, std::ios::beg );
|
||||
}
|
||||
|
||||
pstream->clear();
|
||||
|
||||
// Substitute symbol locations with member indexes
|
||||
for ( auto& symbol : symbol_table ) {
|
||||
auto index = 0;
|
||||
const auto it = std::find_if(
|
||||
members_.begin(), members_.end(),
|
||||
[&]( const Member& m ) { return m.filepos == symbol.second; } );
|
||||
if ( it != members_.end() ) {
|
||||
index = (std::uint32_t)std::distance( members_.begin(), it );
|
||||
}
|
||||
symbol.second = index;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Save the archive header
|
||||
//! @param os Output stream to save the header
|
||||
//! @return Error object indicating success or failure
|
||||
Result save_header( std::ostream& os )
|
||||
{
|
||||
if ( !os ) {
|
||||
return { "Output stream is null" };
|
||||
}
|
||||
|
||||
// Write the archive magic string
|
||||
os << ARCH_MAGIC;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Calculate the size of the symbol table
|
||||
//! @return The size of the symbol table in bytes
|
||||
//! The size includes the header, number of symbols, symbol locations, and names
|
||||
//! It also includes padding if the size is odd
|
||||
//! @note The symbol table is saved after the archive header and before the long name directory
|
||||
std::streamoff calculate_symbol_table_size() const
|
||||
{
|
||||
auto num_of_symbols = static_cast<std::uint32_t>( symbol_table.size() );
|
||||
|
||||
// Calculate the symbol table size
|
||||
auto symbol_table_size =
|
||||
HEADER_SIZE +
|
||||
sizeof( num_of_symbols ) + // Size of the number of symbols
|
||||
num_of_symbols *
|
||||
( sizeof( std::uint32_t ) ); // Size of each symbol location
|
||||
for ( const auto& symbol : symbol_table ) {
|
||||
// Size of each symbol name + null terminator
|
||||
symbol_table_size += symbol.first.size() + 1;
|
||||
}
|
||||
|
||||
// Add padding byte if the size is odd
|
||||
symbol_table_size += symbol_table_size % 2;
|
||||
|
||||
return symbol_table_size;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Calculate the relative offsets of members in the archive
|
||||
//! @return A vector of relative offsets for each member
|
||||
//! The offsets are calculated from the start of the archive
|
||||
std::vector<std::uint32_t> calculate_member_relative_offsets()
|
||||
{
|
||||
std::vector<std::uint32_t> member_relative_offset;
|
||||
size_t position = 0;
|
||||
|
||||
member_relative_offset.reserve( members_.size() );
|
||||
for ( const auto& member : members_ ) {
|
||||
// Store the relative offset of the member in the archive
|
||||
member_relative_offset.push_back(
|
||||
static_cast<std::uint32_t>( position ) );
|
||||
position += HEADER_SIZE + member.size +
|
||||
member.size % 2; // Add padding if needed
|
||||
}
|
||||
return member_relative_offset;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Calculate the size of the long names directory
|
||||
//! @return The size of the long names directory in bytes
|
||||
//! The size includes the header and the string table
|
||||
//! It also includes padding if the size is odd
|
||||
//! @note The long names directory is saved after the symbol table and before the members
|
||||
std::streamoff calculate_long_names_dir_size()
|
||||
{
|
||||
return HEADER_SIZE + string_table.size() + string_table.size() % 2;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Save the symbol table to the archive
|
||||
//! @param os Output stream to save the symbol table
|
||||
//! @return Error object indicating success or failure
|
||||
Result save_symbol_table( std::ostream& os )
|
||||
{
|
||||
if ( !os ) {
|
||||
return { "Output stream is null" };
|
||||
}
|
||||
|
||||
auto num_of_symbols = static_cast<std::uint32_t>( symbol_table.size() );
|
||||
if ( num_of_symbols == 0 ) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto symbol_table_size = calculate_symbol_table_size();
|
||||
auto long_names_dir_size = calculate_long_names_dir_size();
|
||||
auto member_relative_offset = calculate_member_relative_offsets();
|
||||
|
||||
// Write the symbol table header
|
||||
os << "/ 0 0 0 0 "
|
||||
<< std::setw( FIELD_SIZE_SIZE ) << std::left << std::dec
|
||||
<< symbol_table_size - HEADER_SIZE << HEADER_END_MAGIC;
|
||||
|
||||
// Write the number of symbols
|
||||
char buf[4];
|
||||
buf[0] = static_cast<char>( ( num_of_symbols >> 24 ) & 0xFF );
|
||||
buf[1] = static_cast<char>( ( num_of_symbols >> 16 ) & 0xFF );
|
||||
buf[2] = static_cast<char>( ( num_of_symbols >> 8 ) & 0xFF );
|
||||
buf[3] = static_cast<char>( ( num_of_symbols >> 0 ) & 0xFF );
|
||||
// Write the number of symbols as a 4-byte big-endian integer
|
||||
os.write( buf, sizeof( buf ) );
|
||||
|
||||
// Write symbol locations (location of the member in the archive)
|
||||
auto members_start_from =
|
||||
std::string( ARCH_MAGIC ).size() +
|
||||
static_cast<std::uint32_t>( symbol_table_size ) +
|
||||
static_cast<std::uint32_t>( long_names_dir_size );
|
||||
for ( const auto& symbol : symbol_table ) {
|
||||
auto index = static_cast<std::uint32_t>( symbol.second );
|
||||
auto location = members_start_from + member_relative_offset[index];
|
||||
buf[0] = static_cast<char>( ( location >> 24 ) & 0xFF );
|
||||
buf[1] = static_cast<char>( ( location >> 16 ) & 0xFF );
|
||||
buf[2] = static_cast<char>( ( location >> 8 ) & 0xFF );
|
||||
buf[3] = static_cast<char>( ( location >> 0 ) & 0xFF );
|
||||
os.write( buf, sizeof( buf ) );
|
||||
}
|
||||
if ( os.fail() ) {
|
||||
return { "Failed to write symbol table" };
|
||||
}
|
||||
|
||||
// Write symbol names
|
||||
for ( const auto& symbol : symbol_table ) {
|
||||
os << symbol.first << '\0'; // Null-terminated string
|
||||
}
|
||||
if ( os.tellp() % 2 != 0 ) {
|
||||
os << '\x0A';
|
||||
}
|
||||
|
||||
if ( os.fail() ) {
|
||||
return { "Failed to write symbol table" };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Save the long name directory to the archive
|
||||
//! @param os Output stream to save the long name directory
|
||||
//! @return Error object indicating success or failure
|
||||
Result save_long_name_directory( std::ostream& os )
|
||||
{
|
||||
if ( !os ) {
|
||||
return { "Output stream is null" };
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
// Write the long name directory
|
||||
os << "// "
|
||||
<< std::setw( FIELD_SIZE_SIZE ) << std::left << std::dec << string_table.size()
|
||||
<< HEADER_END_MAGIC
|
||||
<< string_table;
|
||||
// clang-format on
|
||||
|
||||
if ( string_table.size() % 2 != 0 ) {
|
||||
// Write a padding byte if the size is odd
|
||||
os.put( '\x0A' );
|
||||
}
|
||||
|
||||
if ( os.fail() ) {
|
||||
return { "Failed to write member data" };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Save the member information to the archive
|
||||
//! @param os Output stream to save the member information
|
||||
//! @return Error object indicating success or failure
|
||||
Result save_members( std::ostream& os )
|
||||
{
|
||||
if ( !os ) {
|
||||
return { "Output stream is null" };
|
||||
}
|
||||
|
||||
for ( const auto& member : members_ ) {
|
||||
// clang-format off
|
||||
// Write the member header
|
||||
os << std::setw( FIELD_NAME_SIZE ) << std::left << member.short_name
|
||||
<< std::setw( FIELD_DATE_SIZE ) << std::left << member.date
|
||||
<< std::setw( FIELD_UID_SIZE ) << std::left << member.uid
|
||||
<< std::setw( FIELD_GID_SIZE ) << std::left << member.gid
|
||||
<< std::setw( FIELD_MODE_SIZE ) << std::left << std::oct << member.mode
|
||||
<< std::setw( FIELD_SIZE_SIZE ) << std::left << std::dec << member.size
|
||||
<< HEADER_END_MAGIC;
|
||||
// clang-format on
|
||||
|
||||
// Write the content of the member
|
||||
os.write( member.data().data(), member.size );
|
||||
if ( os.fail() ) {
|
||||
return { "Failed to write member data" };
|
||||
}
|
||||
if ( member.size % 2 != 0 ) {
|
||||
// Write a padding byte if the size is odd
|
||||
os.put( '\x0A' );
|
||||
if ( os.fail() ) {
|
||||
return { "Failed to write padding byte" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Read the symbol table from the archive symbol table member
|
||||
//! @return Error object indicating success or failure
|
||||
Result load_symbol_table()
|
||||
{
|
||||
char buf[4];
|
||||
pstream->read( buf, sizeof( buf ) );
|
||||
if ( pstream->gcount() < sizeof( buf ) ) {
|
||||
return { "Failed to read symbol table" };
|
||||
}
|
||||
|
||||
std::uint32_t num_of_symbols =
|
||||
( static_cast<std::uint8_t>( buf[0] ) << 24 ) |
|
||||
( static_cast<std::uint8_t>( buf[1] ) << 16 ) |
|
||||
( static_cast<std::uint8_t>( buf[2] ) << 8 ) |
|
||||
( static_cast<std::uint8_t>( buf[3] ) << 0 );
|
||||
|
||||
std::vector<std::pair<std::uint32_t, std::string>> v( num_of_symbols );
|
||||
|
||||
// Read symbol locations
|
||||
for ( std::uint32_t i = 0; i < num_of_symbols; ++i ) {
|
||||
pstream->read( buf, sizeof( buf ) );
|
||||
if ( pstream->gcount() < sizeof( buf ) ) {
|
||||
return { "Failed to read symbol table" };
|
||||
}
|
||||
std::uint32_t member_location =
|
||||
( static_cast<std::uint8_t>( buf[0] ) << 24 ) |
|
||||
( static_cast<std::uint8_t>( buf[1] ) << 16 ) |
|
||||
( static_cast<std::uint8_t>( buf[2] ) << 8 ) |
|
||||
( static_cast<std::uint8_t>( buf[3] ) << 0 );
|
||||
v[i].first = member_location;
|
||||
}
|
||||
|
||||
// Read symbol names
|
||||
for ( std::uint32_t i = 0; i < num_of_symbols; ++i ) {
|
||||
std::string sym_name;
|
||||
std::getline( *pstream, sym_name, '\0' );
|
||||
v[i].second = sym_name;
|
||||
}
|
||||
|
||||
// Copy to symbol_table map
|
||||
for ( const auto& pair : v ) {
|
||||
symbol_table[pair.second] = pair.first;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//! @brief Convert a short name to a long name using the long name directory
|
||||
//! @param short_name The short name to convert
|
||||
//! @return The long name
|
||||
std::optional<std::string> convert_name( std::string_view short_name )
|
||||
{
|
||||
auto pos = short_name.find( '/' );
|
||||
if ( pos == 0 ) {
|
||||
if ( short_name.size() < 3 ) {
|
||||
return std::nullopt;
|
||||
}
|
||||
size_t offset_in_dir = 0;
|
||||
try {
|
||||
offset_in_dir = std::stoul( std::string(
|
||||
short_name.substr( 1, short_name.size() - 2 ) ) );
|
||||
}
|
||||
catch ( const std::exception& ) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if ( offset_in_dir >= string_table.size() ) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto end = string_table.find( '/', offset_in_dir );
|
||||
if ( end == std::string::npos || end <= offset_in_dir ) {
|
||||
return std::nullopt;
|
||||
}
|
||||
std::string long_name =
|
||||
string_table.substr( offset_in_dir, end - offset_in_dir );
|
||||
return long_name;
|
||||
}
|
||||
else if ( pos != std::string::npos && pos != 0 &&
|
||||
pos < short_name.size() ) {
|
||||
return std::string( short_name.substr( 0, pos ) );
|
||||
}
|
||||
|
||||
return std::string( short_name );
|
||||
}
|
||||
|
||||
public:
|
||||
Members members; //!< Members object
|
||||
|
||||
protected:
|
||||
static constexpr const char* ARCH_MAGIC =
|
||||
"!<arch>\x0A"; ///< Archive magic string
|
||||
static constexpr const char* HEADER_END_MAGIC =
|
||||
"\x60\x0A"; ///< End of header magic
|
||||
static constexpr std::streamsize HEADER_SIZE =
|
||||
60; ///< Size of archive header
|
||||
static constexpr unsigned int FIELD_NAME_SIZE = 16;
|
||||
static constexpr unsigned int FIELD_DATE_SIZE = 12;
|
||||
static constexpr unsigned int FIELD_UID_SIZE = 6;
|
||||
static constexpr unsigned int FIELD_GID_SIZE = 6;
|
||||
static constexpr unsigned int FIELD_MODE_SIZE = 8;
|
||||
static constexpr unsigned int FIELD_SIZE_SIZE = 10;
|
||||
|
||||
//!< Pointer to the input stream
|
||||
//! It is used to read the archive members
|
||||
//! data even after the archive is loaded
|
||||
std::shared_ptr<std::istream> pstream = nullptr;
|
||||
std::vector<Member> members_; //!< Vector of archive members
|
||||
//!< Symbol table
|
||||
//!< This is a map from symbol names to member indexes
|
||||
//!< The member index is the index in the members_ vector
|
||||
//!< This allows for quick lookup of symbols by name
|
||||
std::unordered_map<std::string, size_t> symbol_table;
|
||||
std::string string_table; //!< Long names for members
|
||||
};
|
||||
|
||||
} // namespace ARIO
|
||||
|
||||
#endif // ARIO_HPP
|
||||
@@ -1,5 +0,0 @@
|
||||
# Basic CMake package config file
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
check_required_components("@PROJECT_NAME@")
|
||||
|
Before Width: | Height: | Size: 207 B |
|
Before Width: | Height: | Size: 837 B |
|
Before Width: | Height: | Size: 374 B |
|
Before Width: | Height: | Size: 889 B |
|
Before Width: | Height: | Size: 329 B |
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M10.428,10.411h0.56c3.78,0,4.788-1.96,4.872-3.444h3.22v19.88h-3.92V13.154h-4.732V10.411z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 718 B |
|
Before Width: | Height: | Size: 929 B |
|
Before Width: | Height: | Size: 361 B |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.815,10.758h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76v17.04h-3.36V13.11H3.815V10.758z"/>
|
||||
<path style="fill:#FFFFFF;" d="M22.175,7.806c4.009,0,5.904,2.76,5.904,8.736c0,5.975-1.896,8.76-5.904,8.76
|
||||
c-4.008,0-5.904-2.785-5.904-8.76C16.271,10.566,18.167,7.806,22.175,7.806z M22.175,22.613c1.921,0,2.448-1.68,2.448-6.071
|
||||
c0-4.393-0.527-6.049-2.448-6.049c-1.92,0-2.448,1.656-2.448,6.049C19.727,20.934,20.255,22.613,22.175,22.613z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 202 B |
|
Before Width: | Height: | Size: 565 B |
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M5.209,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H5.209V10.412z"/>
|
||||
<path style="fill:#FFFFFF;" d="M18.553,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.359V12.764h-4.056V10.412z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 843 B |
|
Before Width: | Height: | Size: 210 B |
|
Before Width: | Height: | Size: 617 B |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M4.813,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H4.813V10.412z"/>
|
||||
<path style="fill:#FFFFFF;" d="M17.316,13.484c0-5.545,4.056-6.024,5.568-6.024c3.265,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.553,5.544c-2.256,1.584-3.432,2.353-3.815,3.145h7.392V24.5h-11.64c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.353-2.424c-2.352,0-2.423,1.944-2.447,3.192H17.316z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 209 B |
|
Before Width: | Height: | Size: 623 B |
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.813,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H3.813V10.412z"/>
|
||||
<path style="fill:#FFFFFF;" d="M20.611,14.636h0.529c1.008,0,2.855-0.096,2.855-2.304c0-0.624-0.288-2.185-2.137-2.185
|
||||
c-2.303,0-2.303,2.185-2.303,2.784h-3.12c0-3.191,1.8-5.472,5.64-5.472c2.279,0,5.279,1.152,5.279,4.752
|
||||
c0,1.728-1.08,2.808-2.039,3.24V15.5c0.6,0.168,2.568,1.056,2.568,3.96c0,3.216-2.377,5.496-5.809,5.496
|
||||
c-1.607,0-5.928-0.36-5.928-5.688h3.288l-0.024,0.024c0,0.912,0.24,2.976,2.496,2.976c1.344,0,2.52-0.911,2.52-2.808
|
||||
c0-2.328-2.256-2.424-3.816-2.424V14.636z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 205 B |
|
Before Width: | Height: | Size: 411 B |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M4.146,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H4.146V10.412z"/>
|
||||
<path style="fill:#FFFFFF;" d="M28.457,20.732h-1.896V24.5h-3.36v-3.768h-6.72v-2.904L22.746,7.46h3.815v10.656h1.896V20.732z
|
||||
M23.201,18.116c0-4.128,0.072-6.792,0.072-7.32h-0.048l-4.272,7.32H23.201z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 923 B |
|
Before Width: | Height: | Size: 210 B |
|
Before Width: | Height: | Size: 640 B |
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.479,11.079h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76v17.04h-3.36V13.43H3.479V11.079z"/>
|
||||
<path style="fill:#FFFFFF;" d="M19.342,14.943c0.625-0.433,1.392-0.937,3.048-0.937c2.279,0,5.16,1.584,5.16,5.496
|
||||
c0,2.328-1.176,6.121-6.192,6.121c-2.664,0-5.376-1.584-5.544-5.016h3.36c0.144,1.391,0.888,2.326,2.376,2.326
|
||||
c1.607,0,2.544-1.367,2.544-3.191c0-1.512-0.72-3.047-2.496-3.047c-0.456,0-1.608,0.023-2.256,1.223l-3-0.143l1.176-9.361h9.36
|
||||
v2.832h-6.937L19.342,14.943z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.813,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H3.813V10.412z"/>
|
||||
<path style="fill:#FFFFFF;" d="M24.309,11.78c-0.097-0.96-0.721-1.633-1.969-1.633c-2.184,0-2.688,2.496-2.808,4.704L19.58,14.9
|
||||
c0.456-0.624,1.296-1.416,3.191-1.416c3.529,0,5.209,2.712,5.209,5.256c0,3.72-2.28,6.216-5.568,6.216
|
||||
c-5.16,0-6.168-4.32-6.168-8.568c0-3.24,0.432-8.928,6.336-8.928c0.695,0,2.641,0.264,3.48,1.104
|
||||
c0.936,0.912,1.271,1.416,1.584,3.217H24.309z M22.172,16.172c-1.271,0-2.568,0.792-2.568,2.928c0,1.849,1.056,3.168,2.664,3.168
|
||||
c1.225,0,2.353-0.936,2.353-3.239C24.62,16.868,23.229,16.172,22.172,16.172z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.479,11.079h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76v17.04h-3.36V13.43H3.479V11.079z"/>
|
||||
<path style="fill:#FFFFFF;" d="M27.838,11.006c-1.631,1.776-5.807,6.816-6.215,14.16h-3.457c0.36-6.816,4.632-12.24,6.072-13.776
|
||||
h-8.472l0.072-2.976h12V11.006z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 883 B |
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M4.813,10.412h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76V24.5h-3.36V12.764H4.813V10.412z"/>
|
||||
<path style="fill:#FFFFFF;" d="M23.172,24.956c-4.392,0-5.904-2.856-5.904-5.185c0-0.863,0-3.119,2.592-4.319
|
||||
c-1.344-0.672-2.064-1.752-2.064-3.336c0-2.904,2.328-4.656,5.304-4.656c3.528,0,5.4,2.088,5.4,4.44
|
||||
c0,1.464-0.6,2.712-1.968,3.432c1.632,0.815,2.544,1.896,2.544,4.104C29.076,21.596,27.684,24.956,23.172,24.956z M23.124,16.916
|
||||
c-1.224,0-2.4,0.792-2.4,2.64c0,1.632,0.936,2.712,2.472,2.712c1.752,0,2.424-1.512,2.424-2.688
|
||||
C25.62,18.38,24.996,16.916,23.124,16.916z M25.284,12.26c0-1.296-0.888-2.112-1.968-2.112c-1.512,0-2.305,0.864-2.305,2.112
|
||||
c0,1.008,0.744,2.112,2.185,2.112C24.516,14.372,25.284,13.484,25.284,12.26z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M4.146,10.746h0.48c3.24,0,4.104-1.681,4.176-2.952h2.76v17.041h-3.36V13.097H4.146V10.746z"/>
|
||||
<path style="fill:#FFFFFF;" d="M20.225,20.898v0.023c0.192,1.176,0.936,1.68,1.968,1.68c1.392,0,2.783-1.176,2.808-4.752
|
||||
l-0.048-0.049c-0.768,1.152-2.088,1.441-3.24,1.441c-3.264,0-5.16-2.473-5.16-5.329c0-4.176,2.472-6.12,5.808-6.12
|
||||
c5.904,0,6,6.36,6,8.76c0,6.601-3.12,8.736-6.192,8.736c-2.904,0-4.992-1.68-5.28-4.391H20.225z M22.434,16.553
|
||||
c1.176,0,2.472-0.84,2.472-2.855c0-1.944-0.841-3.145-2.568-3.145c-0.864,0-2.424,0.433-2.424,2.88
|
||||
C19.913,16.001,21.161,16.553,22.434,16.553z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 907 B |
|
Before Width: | Height: | Size: 353 B |
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M9.668,12.328c0-6.469,4.732-7.028,6.496-7.028c3.808,0,6.833,2.24,6.833,6.271
|
||||
c0,3.416-2.213,5.152-4.145,6.469c-2.632,1.848-4.004,2.744-4.452,3.668h8.624v3.472H9.444c0.14-2.324,0.308-4.76,4.62-7.896
|
||||
c3.584-2.604,5.012-3.612,5.012-5.853c0-1.315-0.84-2.828-2.744-2.828c-2.744,0-2.828,2.269-2.856,3.725H9.668z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 943 B |
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
|
||||
<path style="fill:#FFFFFF;" d="M23.172,7.46c4.008,0,5.904,2.76,5.904,8.736c0,5.976-1.896,8.76-5.904,8.76
|
||||
s-5.904-2.784-5.904-8.76C17.268,10.22,19.164,7.46,23.172,7.46z M23.172,22.268c1.92,0,2.448-1.68,2.448-6.071
|
||||
c0-4.393-0.528-6.049-2.448-6.049s-2.448,1.656-2.448,6.049C20.724,20.588,21.252,22.268,23.172,22.268z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M5.306,13.151c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392v2.976H5.114c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H5.306z"/>
|
||||
<path style="fill:#FFFFFF;" d="M19.49,10.079h0.48c3.239,0,4.104-1.681,4.176-2.952h2.761v17.04h-3.361V12.431H19.49V10.079z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
|
||||
<path style="fill:#FFFFFF;" d="M17.316,13.484c0-5.545,4.056-6.024,5.568-6.024c3.265,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.553,5.544c-2.256,1.584-3.432,2.353-3.815,3.145h7.392V24.5h-11.64c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.353-2.424c-2.352,0-2.423,1.944-2.447,3.192H17.316z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
|
||||
<path style="fill:#FFFFFF;" d="M21.612,14.636h0.528c1.008,0,2.855-0.096,2.855-2.304c0-0.624-0.287-2.185-2.136-2.185
|
||||
c-2.304,0-2.304,2.185-2.304,2.784h-3.12c0-3.191,1.8-5.472,5.64-5.472c2.28,0,5.28,1.152,5.28,4.752
|
||||
c0,1.728-1.08,2.808-2.04,3.24V15.5c0.6,0.168,2.568,1.056,2.568,3.96c0,3.216-2.377,5.496-5.809,5.496
|
||||
c-1.607,0-5.928-0.36-5.928-5.688h3.288l-0.024,0.024c0,0.912,0.24,2.976,2.496,2.976c1.344,0,2.521-0.911,2.521-2.808
|
||||
c0-2.328-2.257-2.424-3.816-2.424V14.636z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M4.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H4.78c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H4.972z"/>
|
||||
<path style="fill:#FFFFFF;" d="M30.124,20.732h-1.896V24.5h-3.36v-3.768h-6.72v-2.904L24.412,7.46h3.816v10.656h1.896V20.732z
|
||||
M24.868,18.116c0-4.128,0.071-6.792,0.071-7.32h-0.047l-4.272,7.32H24.868z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
|
||||
<path style="fill:#FFFFFF;" d="M20.676,14.276c0.624-0.433,1.393-0.937,3.049-0.937c2.279,0,5.16,1.584,5.16,5.496
|
||||
c0,2.328-1.177,6.12-6.193,6.12c-2.664,0-5.375-1.584-5.543-5.016h3.36c0.144,1.392,0.889,2.327,2.376,2.327
|
||||
c1.608,0,2.544-1.367,2.544-3.191c0-1.513-0.72-3.048-2.496-3.048c-0.455,0-1.607,0.023-2.256,1.224l-3-0.144l1.176-9.36h9.36
|
||||
v2.832h-6.937L20.676,14.276z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
|
||||
<path style="fill:#FFFFFF;" d="M25.309,11.78c-0.097-0.96-0.721-1.633-1.969-1.633c-2.184,0-2.688,2.496-2.808,4.704L20.58,14.9
|
||||
c0.456-0.624,1.296-1.416,3.191-1.416c3.529,0,5.209,2.712,5.209,5.256c0,3.72-2.28,6.216-5.568,6.216
|
||||
c-5.16,0-6.168-4.32-6.168-8.568c0-3.24,0.432-8.928,6.336-8.928c0.695,0,2.641,0.264,3.48,1.104
|
||||
c0.936,0.912,1.271,1.416,1.584,3.217H25.309z M23.172,16.172c-1.271,0-2.568,0.792-2.568,2.928c0,1.849,1.056,3.168,2.664,3.168
|
||||
c1.225,0,2.353-0.936,2.353-3.239C25.62,16.868,24.229,16.172,23.172,16.172z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
|
||||
<path style="fill:#FFFFFF;" d="M29.172,10.34c-1.632,1.776-5.808,6.816-6.216,14.16H19.5c0.36-6.816,4.632-12.24,6.072-13.776
|
||||
H17.1l0.072-2.976h12V10.34z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
|
||||
<path style="fill:#FFFFFF;" d="M23.172,24.956c-4.392,0-5.904-2.856-5.904-5.185c0-0.863,0-3.119,2.592-4.319
|
||||
c-1.344-0.672-2.064-1.752-2.064-3.336c0-2.904,2.328-4.656,5.304-4.656c3.528,0,5.4,2.088,5.4,4.44
|
||||
c0,1.464-0.6,2.712-1.968,3.432c1.632,0.815,2.544,1.896,2.544,4.104C29.076,21.596,27.684,24.956,23.172,24.956z M23.124,16.916
|
||||
c-1.224,0-2.4,0.792-2.4,2.64c0,1.632,0.936,2.712,2.472,2.712c1.752,0,2.424-1.512,2.424-2.688
|
||||
C25.62,18.38,24.996,16.916,23.124,16.916z M25.284,12.26c0-1.296-0.888-2.112-1.968-2.112c-1.512,0-2.305,0.864-2.305,2.112
|
||||
c0,1.008,0.744,2.112,2.185,2.112C24.516,14.372,25.284,13.484,25.284,12.26z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M3.972,13.484c0-5.545,4.056-6.024,5.568-6.024c3.264,0,5.856,1.92,5.856,5.376
|
||||
c0,2.928-1.896,4.416-3.552,5.544c-2.256,1.584-3.432,2.353-3.816,3.145h7.392V24.5H3.78c0.12-1.992,0.264-4.08,3.96-6.768
|
||||
c3.072-2.232,4.296-3.097,4.296-5.017c0-1.128-0.72-2.424-2.352-2.424c-2.352,0-2.424,1.944-2.448,3.192H3.972z"/>
|
||||
<path style="fill:#FFFFFF;" d="M20.893,20.564v0.023c0.191,1.176,0.936,1.68,1.967,1.68c1.393,0,2.785-1.176,2.809-4.752
|
||||
l-0.048-0.048c-0.769,1.152-2.088,1.44-3.24,1.44c-3.264,0-5.16-2.473-5.16-5.328c0-4.176,2.472-6.12,5.807-6.12
|
||||
c5.904,0,6.001,6.36,6.001,8.76c0,6.601-3.12,8.736-6.192,8.736c-2.904,0-4.992-1.68-5.28-4.392H20.893z M23.1,16.22
|
||||
c1.176,0,2.473-0.84,2.473-2.855c0-1.944-0.84-3.145-2.568-3.145c-0.863,0-2.424,0.433-2.424,2.88
|
||||
C20.58,15.668,21.828,16.22,23.1,16.22z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 914 B |
|
Before Width: | Height: | Size: 350 B |
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M15.127,14.005h0.616c1.176,0,3.332-0.112,3.332-2.688c0-0.728-0.336-2.548-2.492-2.548
|
||||
c-2.688,0-2.688,2.548-2.688,3.248h-3.64c0-3.724,2.1-6.384,6.58-6.384c2.66,0,6.16,1.344,6.16,5.544
|
||||
c0,2.016-1.261,3.276-2.38,3.78v0.056c0.699,0.196,2.996,1.232,2.996,4.62c0,3.752-2.772,6.412-6.776,6.412
|
||||
c-1.876,0-6.916-0.42-6.916-6.636h3.836l-0.028,0.027c0,1.064,0.28,3.473,2.912,3.473c1.568,0,2.94-1.064,2.94-3.276
|
||||
c0-2.716-2.632-2.828-4.452-2.828V14.005z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M8.268,14.636h0.528c1.008,0,2.856-0.096,2.856-2.304c0-0.624-0.288-2.185-2.136-2.185
|
||||
c-2.304,0-2.304,2.185-2.304,2.784h-3.12c0-3.191,1.8-5.472,5.64-5.472c2.28,0,5.28,1.152,5.28,4.752
|
||||
c0,1.728-1.08,2.808-2.04,3.24V15.5c0.6,0.168,2.568,1.056,2.568,3.96c0,3.216-2.376,5.496-5.808,5.496
|
||||
c-1.608,0-5.928-0.36-5.928-5.688h3.288l-0.024,0.024c0,0.912,0.24,2.976,2.496,2.976c1.344,0,2.52-0.911,2.52-2.808
|
||||
c0-2.328-2.256-2.424-3.816-2.424V14.636z"/>
|
||||
<path style="fill:#FFFFFF;" d="M23.172,7.46c4.008,0,5.904,2.76,5.904,8.736c0,5.976-1.896,8.76-5.904,8.76
|
||||
s-5.904-2.784-5.904-8.76C17.268,10.22,19.164,7.46,23.172,7.46z M23.172,22.268c1.92,0,2.448-1.68,2.448-6.071
|
||||
c0-4.393-0.528-6.049-2.448-6.049s-2.448,1.656-2.448,6.049C20.724,20.588,21.252,22.268,23.172,22.268z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 907 B |
|
Before Width: | Height: | Size: 345 B |
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M21.891,20.784h-2.212v4.396h-3.92v-4.396h-7.84v-3.389L15.227,5.3h4.452v12.432h2.212V20.784z
|
||||
M15.759,17.731c0-4.815,0.084-7.924,0.084-8.54h-0.056l-4.984,8.54H15.759z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 799 B |
|
Before Width: | Height: | Size: 916 B |
|
Before Width: | Height: | Size: 348 B |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M14.035,14.252c0.728-0.504,1.624-1.092,3.556-1.092c2.66,0,6.02,1.848,6.02,6.411
|
||||
c0,2.717-1.372,7.141-7.224,7.141c-3.108,0-6.272-1.849-6.468-5.853h3.92c0.168,1.624,1.036,2.717,2.772,2.717
|
||||
c1.876,0,2.968-1.597,2.968-3.725c0-1.764-0.839-3.556-2.912-3.556c-0.532,0-1.876,0.028-2.632,1.428l-3.5-0.168l1.372-10.92
|
||||
h10.919v3.304h-8.092L14.035,14.252z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 985 B |
|
Before Width: | Height: | Size: 218 B |
|
Before Width: | Height: | Size: 355 B |
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M19.106,10.673c-0.112-1.12-0.84-1.904-2.296-1.904c-2.548,0-3.136,2.912-3.276,5.488l0.056,0.056
|
||||
c0.532-0.728,1.512-1.651,3.724-1.651c4.116,0,6.077,3.164,6.077,6.131c0,4.34-2.66,7.252-6.497,7.252
|
||||
c-6.02,0-7.196-5.039-7.196-9.996c0-3.78,0.504-10.416,7.392-10.416c0.812,0,3.08,0.308,4.061,1.288
|
||||
c1.092,1.063,1.483,1.652,1.848,3.752H19.106z M16.614,15.797c-1.484,0-2.996,0.924-2.996,3.416c0,2.156,1.232,3.697,3.108,3.697
|
||||
c1.428,0,2.745-1.094,2.745-3.781C19.471,16.609,17.846,15.797,16.614,15.797z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 907 B |
|
Before Width: | Height: | Size: 344 B |
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M24.28,9.66c-1.904,2.071-6.776,7.951-7.252,16.52h-4.032c0.42-7.952,5.404-14.28,7.084-16.072
|
||||
h-9.884l0.084-3.472h14V9.66z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 754 B |
|
Before Width: | Height: | Size: 918 B |
|
Before Width: | Height: | Size: 357 B |
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M16.28,26.712c-5.124,0-6.888-3.332-6.888-6.048c0-1.009,0-3.641,3.024-5.04
|
||||
c-1.568-0.784-2.408-2.044-2.408-3.893c0-3.388,2.716-5.432,6.188-5.432c4.116,0,6.3,2.436,6.3,5.18
|
||||
c0,1.708-0.7,3.164-2.296,4.004c1.903,0.952,2.968,2.212,2.968,4.788C23.168,22.792,21.544,26.712,16.28,26.712z M16.224,17.332
|
||||
c-1.428,0-2.8,0.924-2.8,3.08c0,1.903,1.092,3.164,2.884,3.164c2.043,0,2.829-1.765,2.829-3.137
|
||||
C19.137,19.04,18.408,17.332,16.224,17.332z M18.744,11.899c0-1.512-1.036-2.464-2.296-2.464c-1.764,0-2.688,1.008-2.688,2.464
|
||||
c0,1.177,0.868,2.464,2.548,2.464C17.848,14.363,18.744,13.328,18.744,11.899z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 923 B |
|
Before Width: | Height: | Size: 357 B |
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY ns_svg "http://www.w3.org/2000/svg">
|
||||
<!ENTITY ns_xlink "http://www.w3.org/1999/xlink">
|
||||
]>
|
||||
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="33" height="33" viewBox="0 0 33 33"
|
||||
style="overflow:visible;enable-background:new 0 0 33 33;" xml:space="preserve">
|
||||
<circle style="stroke:#000000;" cx="16.5" cy="16.5" r="16"/>
|
||||
<g>
|
||||
<g style="enable-background:new ;">
|
||||
<path style="fill:#FFFFFF;" d="M13.953,21.921v0.027c0.224,1.372,1.092,1.961,2.296,1.961c1.624,0,3.248-1.372,3.276-5.545
|
||||
l-0.057-0.056c-0.896,1.344-2.436,1.68-3.78,1.68c-3.808,0-6.02-2.884-6.02-6.216c0-4.872,2.884-7.14,6.776-7.14
|
||||
c6.888,0,7,7.42,7,10.22c0,7.7-3.641,10.192-7.224,10.192c-3.388,0-5.824-1.96-6.16-5.124H13.953z M16.529,16.853
|
||||
c1.372,0,2.884-0.979,2.884-3.332c0-2.268-0.98-3.668-2.996-3.668c-1.008,0-2.828,0.504-2.828,3.36
|
||||
C13.589,16.209,15.045,16.853,16.529,16.853z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 743 B |
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 9.0, SVG Export Plug-In -->
|
||||
<!DOCTYPE svg [
|
||||
<!ENTITY st0 "fill:#FFFFFF;stroke:none;">
|
||||
<!ENTITY st1 "fill:#FFFFFF;stroke-width:6.6112;stroke-linecap:round;stroke-linejoin:round;">
|
||||
<!ENTITY st2 "stroke:#FFFFFF;stroke-width:6.6112;">
|
||||
<!ENTITY st3 "fill:none;stroke:none;">
|
||||
<!ENTITY st4 "fill-rule:nonzero;clip-rule:nonzero;stroke:#000000;stroke-miterlimit:4;">
|
||||
<!ENTITY st5 "stroke:none;">
|
||||
]>
|
||||
<svg width="48pt" height="48pt" viewBox="0 0 48 48" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Layer_x0020_3" style="&st4;">
|
||||
<g>
|
||||
<path style="&st2;" d="M41.7,35.3L26.6,9.4c-0.6-1-1.7-1.7-2.9-1.6c-1.2,0-2.3,0.7-2.9,1.7L6.3,35.4c-0.6,1-0.6,2.3,0,3.3c0.6,1,1.7,1.6,2.9,1.6h29.6c1.2,0,2.3-0.6,2.9-1.7c0.6-1,0.6-2.3,0-3.3z"/>
|
||||
<path style="&st1;" d="M23.7,11L9.2,37h29.6L23.7,11z"/>
|
||||
<path style="&st0;" d="M23.7,11.9L10.3,36.1h27.5l-14-24.1z"/>
|
||||
<g>
|
||||
<path style="&st5;" d="M24.1,34c-1.1,0-1.8-0.8-1.8-1.8c0-1.1,0.7-1.8,1.8-1.8c1.1,0,1.8,0.7,1.8,1.8c0,1-0.7,1.8-1.8,1.8h0z M22.9,29.3l-0.4-9.1h3.2l-0.4,9.1h-2.3z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="crop_x0020_marks" style="&st4;">
|
||||
<path style="&st3;" d="M48,48H0V0h48v48z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |