/* Copyright 2017 - 2026 R. Thomas
* Copyright 2017 - 2026 Quarkslab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "LIEF/ELF/hash.hpp"
#include "ELF/Structures.hpp"
#include "LIEF/ELF/NoteDetails/core/CorePrPsInfo.hpp"
#include "LIEF/BinaryStream/SpanStream.hpp"
#include "LIEF/iostream.hpp"
#include "spdlog/fmt/fmt.h"
namespace LIEF::ELF {
template<class ELF_T>
inline result<CorePrPsInfo::info_t>
get_info_impl(const Note::description_t& description) {
using Elf_Prpsinfo = typename ELF_T::Elf_Prpsinfo;
CorePrPsInfo::info_t info;
auto stream = SpanStream::from_vector(description);
if (!stream) {
return make_error_code(get_error(stream));
}
auto raw = stream->read<Elf_Prpsinfo>();
if (!raw) {
return make_error_code(get_error(raw));
}
info.state = raw->pr_state;
info.sname = raw->pr_sname;
info.zombie = static_cast<bool>(raw->pr_zomb);
info.nice = raw->pr_nice;
info.flag = raw->pr_flag;
info.uid = raw->pr_uid;
info.gid = raw->pr_gid;
info.pid = raw->pr_pid;
info.ppid = raw->pr_ppid;
info.pgrp = raw->pr_pgrp;
info.sid = raw->pr_sid;
info.filename = std::string(raw->pr_fname, sizeof(Elf_Prpsinfo::pr_fname));
info.args = std::string(raw->pr_psargs, sizeof(Elf_Prpsinfo::pr_psargs));
return info;
}
template<class ELF_T>
inline ok_error_t write_info_impl(Note::description_t& description,
const CorePrPsInfo::info_t& info) {
using Elf_Prpsinfo = typename ELF_T::Elf_Prpsinfo;
Elf_Prpsinfo raw;
std::memset(reinterpret_cast<void*>(&raw), 0, sizeof(Elf_Prpsinfo));
raw.pr_state = info.state;
raw.pr_sname = info.sname;
raw.pr_zomb = static_cast<char>(info.zombie);
raw.pr_nice = info.nice;
raw.pr_flag = info.flag;
raw.pr_uid = info.uid;
raw.pr_gid = info.gid;
raw.pr_pid = info.pid;
raw.pr_ppid = info.ppid;
raw.pr_pgrp = info.pgrp;
raw.pr_sid = info.sid;
std::string filename = info.filename;
filename.resize(sizeof(Elf_Prpsinfo::pr_fname));
std::string args = info.args;
args.resize(sizeof(Elf_Prpsinfo::pr_psargs));
std::move(filename.begin(), filename.end(), raw.pr_fname);
std::move(args.begin(), args.end(), raw.pr_psargs);
vector_iostream ios;
ios.write(raw);
ios.move(description);
return ok_t();
}
result<CorePrPsInfo::info_t> CorePrPsInfo::info() const {
return class_ == Header::CLASS::ELF32 ?
get_info_impl<details::ELF32>(description_) :
get_info_impl<details::ELF64>(description_);
}
void CorePrPsInfo::info(const info_t& info) {
class_ == Header::CLASS::ELF32 ?
write_info_impl<details::ELF32>(description_, info) :
write_info_impl<details::ELF64>(description_, info);
}
void CorePrPsInfo::accept(Visitor& visitor) const {
visitor.visit(*this);
}
void CorePrPsInfo::dump(std::ostream& os) const {
Note::dump(os);
auto info_res = info();
if (!info_res) {
return;
}
os << '\n';
os << fmt::format(" Path: {} (args: {})\n", info_res->filename_stripped(),
info_res->args_stripped())
<< fmt::format(" UID: {:04d} GID: {:04d} PID: {:04d}\n", info_res->uid,
info_res->gid, info_res->pid)
<< fmt::format(" PPID: {:04d} PGRP: {:04d} SID: {:04d}\n", info_res->ppid,
info_res->pgrp, info_res->sid)
<< fmt::format(" Flag: {:#06x} Nice: {} Zombie: {}\n", info_res->flag,
info_res->nice, info_res->zombie)
<< fmt::format(" State: {:#x} State Name: {}\n", info_res->state,
info_res->sname);
}
} // namespace LIEF::ELF