mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-28 13:43:45 +03:00
6b7ce19161
These instances were detected by searching for files that include stdlib.h, but don't match the regex: \\b(_abort|abort|abs|aligned_alloc|arc4random|arc4random_buf|arc4random_ uniform|atexit|atof|atoi|atol|atoll|bsearch|calloc|clearenv|div|div_t|ex it|_Exit|EXIT_FAILURE|EXIT_SUCCESS|free|getenv|getprogname|grantpt|labs| ldiv|ldiv_t|llabs|lldiv|lldiv_t|malloc|malloc_good_size|malloc_size|mble n|mbstowcs|mbtowc|mkdtemp|mkstemp|mkstemps|mktemp|posix_memalign|posix_o penpt|ptsname|ptsname_r|putenv|qsort|qsort_r|rand|RAND_MAX|random|reallo c|realpath|secure_getenv|serenity_dump_malloc_stats|serenity_setenv|sete nv|setprogname|srand|srandom|strtod|strtof|strtol|strtold|strtoll|strtou l|strtoull|system|unlockpt|unsetenv|wcstombs|wctomb)\\b (Without the linebreaks.) This regex is pessimistic, so there might be more files that don't actually use anything from the stdlib. In theory, one might use LibCPP to detect things like this automatically, but let's do this one step after another.
120 lines
3.4 KiB
C++
120 lines
3.4 KiB
C++
/*
|
|
* Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <AK/DeprecatedString.h>
|
|
#include <AK/StringUtils.h>
|
|
#include <LibCore/ArgsParser.h>
|
|
#include <LibCore/System.h>
|
|
#include <LibMain/Main.h>
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
static bool try_set_offset_and_length_parameters(DeprecatedString const& arg_offset, DeprecatedString const& arg_length, u64& offset, u64& length)
|
|
{
|
|
// TODO: Add support for hex values
|
|
auto possible_offset = arg_offset.to_uint<u64>();
|
|
if (!possible_offset.has_value())
|
|
return false;
|
|
auto possible_length = arg_length.to_uint<u64>();
|
|
if (!possible_length.has_value())
|
|
return false;
|
|
offset = possible_offset.value();
|
|
length = possible_length.value();
|
|
return true;
|
|
}
|
|
|
|
static void try_to_dump_with_memory_mapping(int fd, u64 offset, u64 length)
|
|
{
|
|
VERIFY(fd >= 0);
|
|
u64 mmoffset = offset % sysconf(_SC_PAGESIZE);
|
|
void* mmp = mmap(NULL, mmoffset + length, PROT_READ, MAP_SHARED, fd, offset - mmoffset);
|
|
if (mmp == MAP_FAILED) {
|
|
perror("mmap");
|
|
return;
|
|
}
|
|
|
|
size_t ncomplete = 0;
|
|
while (ncomplete < length) {
|
|
ssize_t nwritten = write(STDOUT_FILENO, static_cast<u8*>(mmp) + ncomplete, length - ncomplete);
|
|
if (nwritten < 0) {
|
|
perror("write");
|
|
return;
|
|
}
|
|
ncomplete += nwritten;
|
|
}
|
|
if (munmap(mmp, mmoffset + length) < 0) {
|
|
perror("munmap");
|
|
}
|
|
}
|
|
|
|
static void try_to_dump_with_read(int fd, u64 offset, u64 length)
|
|
{
|
|
VERIFY(fd >= 0);
|
|
auto rs = lseek(fd, offset, SEEK_SET);
|
|
if (rs < 0) {
|
|
fprintf(stderr, "Couldn't seek to offset %" PRIi64 " while verifying: %s\n", offset, strerror(errno));
|
|
return;
|
|
}
|
|
u8 buf[4096];
|
|
size_t ncomplete = 0;
|
|
while (ncomplete < length) {
|
|
size_t length_to_be_read = min<size_t>((length - ncomplete), sizeof(buf));
|
|
if (read(fd, buf, length_to_be_read) < 0) {
|
|
perror("read");
|
|
return;
|
|
}
|
|
ssize_t nwritten = write(STDOUT_FILENO, buf, length_to_be_read);
|
|
if (nwritten < 0) {
|
|
perror("write");
|
|
return;
|
|
}
|
|
ncomplete += nwritten;
|
|
}
|
|
}
|
|
|
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
|
{
|
|
TRY(Core::System::pledge("stdio rpath"));
|
|
|
|
StringView arg_offset;
|
|
StringView arg_length;
|
|
bool use_read_instead_of_mmap = false;
|
|
Core::ArgsParser args;
|
|
args.add_positional_argument(arg_offset, "Physical Address (Offset)", "offset", Core::ArgsParser::Required::Yes);
|
|
args.add_positional_argument(arg_length, "Length of that region", "length", Core::ArgsParser::Required::Yes);
|
|
args.add_option(use_read_instead_of_mmap, "Read /dev/mem instead of try to map it", nullptr, 'r');
|
|
|
|
args.parse(arguments);
|
|
|
|
u64 offset = 0;
|
|
u64 length = 0;
|
|
if (!try_set_offset_and_length_parameters(arg_offset, arg_length, offset, length)) {
|
|
warnln("pmemdump: Invalid length or offset parameters\n");
|
|
return 1;
|
|
}
|
|
|
|
int fd = open("/dev/mem", O_RDONLY);
|
|
if (fd < 0) {
|
|
perror("open");
|
|
return 1;
|
|
}
|
|
if (use_read_instead_of_mmap)
|
|
try_to_dump_with_read(fd, offset, length);
|
|
else
|
|
try_to_dump_with_memory_mapping(fd, offset, length);
|
|
|
|
close(fd);
|
|
|
|
return 0;
|
|
}
|