diff options
-rw-r--r-- | AK/SharedBuffer.cpp | 114 | ||||
-rw-r--r-- | AK/SharedBuffer.h | 8 | ||||
-rw-r--r-- | Libraries/LibGfx/Bitmap.cpp | 15 | ||||
-rw-r--r-- | Libraries/LibGfx/Font.cpp | 10 | ||||
-rw-r--r-- | Libraries/LibGfx/GIFLoader.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibGfx/JPGLoader.cpp | 36 | ||||
-rw-r--r-- | Libraries/LibGfx/PNGLoader.cpp | 9 | ||||
-rw-r--r-- | Meta/Lagom/CMakeLists.txt | 7 |
8 files changed, 179 insertions, 22 deletions
diff --git a/AK/SharedBuffer.cpp b/AK/SharedBuffer.cpp index c0ce19db74..61782fcb28 100644 --- a/AK/SharedBuffer.cpp +++ b/AK/SharedBuffer.cpp @@ -24,53 +24,137 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifdef __serenity__ +#if defined(__serenity__) || defined(__linux__) -#include <AK/SharedBuffer.h> -#include <AK/kmalloc.h> -#include <Kernel/API/Syscall.h> -#include <stdio.h> -#include <serenity.h> +# include <AK/SharedBuffer.h> +# include <AK/kmalloc.h> +# include <Kernel/API/Syscall.h> +# include <stdio.h> + +# if defined(__serenity__) +# include <serenity.h> +# elif defined(__linux__) +# include <AK/String.h> +# include <fcntl.h> +# include <sys/mman.h> + +static String shbuf_shm_name(int shbuf_id) +{ + return String::format("/serenity-shm:%d", shbuf_id); +} + +# endif namespace AK { RefPtr<SharedBuffer> SharedBuffer::create_with_size(int size) { +# if defined(__serenity__) void* data; int shbuf_id = shbuf_create(size, &data); if (shbuf_id < 0) { perror("shbuf_create"); return nullptr; } +# elif defined(__linux__) + // Not atomic, so don't create shared buffers from many threads too hard under lagom. + static unsigned g_shm_id = 0; + + int shbuf_id = (getpid() << 8) | (g_shm_id++); + int fd = shm_open(shbuf_shm_name(shbuf_id).characters(), O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + if (fd < 0) { + perror("shm_open"); + return nullptr; + } + + if (ftruncate(fd, size) < 0) { + perror("ftruncate"); + return nullptr; + } + + void* data = mmap(nullptr, size + sizeof(size_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) { + perror("mmap"); + return nullptr; + } + size_t* size_data = reinterpret_cast<size_t*>(data); + *size_data = size; + data = reinterpret_cast<u8*>(data) + sizeof(size_t); + + if (close(fd) < 0) { + perror("close"); + return nullptr; + } +# endif return adopt(*new SharedBuffer(shbuf_id, size, data)); } bool SharedBuffer::share_with(pid_t peer) { +# if defined(__serenity__) int ret = shbuf_allow_pid(shbuf_id(), peer); if (ret < 0) { perror("shbuf_allow_pid"); return false; } +# else + (void)peer; +# endif return true; } bool SharedBuffer::share_globally() { +# if defined(__serenity__) int ret = shbuf_allow_all(shbuf_id()); if (ret < 0) { perror("shbuf_allow_all"); return false; } +# endif return true; } RefPtr<SharedBuffer> SharedBuffer::create_from_shbuf_id(int shbuf_id) { +# if defined(__serenity__) size_t size = 0; void* data = shbuf_get(shbuf_id, &size); if (data == (void*)-1) return nullptr; +# elif defined(__linux__) + int fd = shm_open(shbuf_shm_name(shbuf_id).characters(), O_RDWR, S_IRUSR | S_IWUSR); + if (fd < 0) { + perror("shm_open"); + return nullptr; + } + + void* data = mmap(nullptr, sizeof(size_t), PROT_READ, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) { + perror("mmap"); + return nullptr; + } + size_t* size_data = reinterpret_cast<size_t*>(data); + size_t size = *size_data; + if (munmap(data, sizeof(size_t)) < 0) { + perror("munmap"); + return nullptr; + } + + data = mmap(nullptr, size + sizeof(size_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (data == MAP_FAILED) { + perror("mmap"); + return nullptr; + } + + data = reinterpret_cast<u8*>(data) + sizeof(size_t); + + if (close(fd) < 0) { + perror("close"); + return nullptr; + } +# endif + return adopt(*new SharedBuffer(shbuf_id, size, data)); } @@ -84,36 +168,48 @@ SharedBuffer::SharedBuffer(int shbuf_id, int size, void* data) SharedBuffer::~SharedBuffer() { if (m_shbuf_id >= 0) { +# if defined(__serenity__) int rc = shbuf_release(m_shbuf_id); if (rc < 0) { perror("shbuf_release"); } +# elif defined(__linux__) + if (munmap(reinterpret_cast<u8*>(m_data) - sizeof(size_t), m_size + sizeof(size_t)) < 0) + perror("munmap"); + if (shm_unlink(shbuf_shm_name(m_shbuf_id).characters()) < 0) + perror("unlink"); +# endif } } void SharedBuffer::seal() { +# if defined(__serenity__) int rc = shbuf_seal(m_shbuf_id); if (rc < 0) { perror("shbuf_seal"); ASSERT_NOT_REACHED(); } +# endif } void SharedBuffer::set_volatile() { +# if defined(__serenity__) u32 rc = syscall(SC_shbuf_set_volatile, m_shbuf_id, true); ASSERT(rc == 0); +# endif } bool SharedBuffer::set_nonvolatile() { +# if defined(__serenity__) u32 rc = syscall(SC_shbuf_set_volatile, m_shbuf_id, false); if (rc == 0) return true; - if (rc == 1) - return false; - ASSERT_NOT_REACHED(); + ASSERT(rc == 1); +# endif + return false; } } diff --git a/AK/SharedBuffer.h b/AK/SharedBuffer.h index be0b03ac0b..2a46a5a803 100644 --- a/AK/SharedBuffer.h +++ b/AK/SharedBuffer.h @@ -26,10 +26,10 @@ #pragma once -#ifdef __serenity__ +#if defined(__serenity__) || defined(__linux__) -#include <AK/RefCounted.h> -#include <AK/RefPtr.h> +# include <AK/RefCounted.h> +# include <AK/RefPtr.h> namespace AK { @@ -54,7 +54,7 @@ private: int m_shbuf_id { -1 }; int m_size { 0 }; - void* m_data; + void* m_data { nullptr }; }; } diff --git a/Libraries/LibGfx/Bitmap.cpp b/Libraries/LibGfx/Bitmap.cpp index be9845d202..cb8eb05aeb 100644 --- a/Libraries/LibGfx/Bitmap.cpp +++ b/Libraries/LibGfx/Bitmap.cpp @@ -74,8 +74,13 @@ Bitmap::Bitmap(BitmapFormat format, const IntSize& size, Purgeable purgeable) ASSERT(!m_size.is_empty()); ASSERT(!size_would_overflow(format, size)); allocate_palette_from_format(format, {}); +#ifdef __serenity__ int map_flags = purgeable == Purgeable::Yes ? (MAP_PURGEABLE | MAP_PRIVATE) : (MAP_ANONYMOUS | MAP_PRIVATE); m_data = (RGBA32*)mmap_with_name(nullptr, size_in_bytes(), PROT_READ | PROT_WRITE, map_flags, 0, 0, String::format("GraphicsBitmap [%dx%d]", width(), height()).characters()); +#else + int map_flags = (MAP_ANONYMOUS | MAP_PRIVATE); + m_data = (RGBA32*)mmap(nullptr, size_in_bytes(), PROT_READ | PROT_WRITE, map_flags, 0, 0); +#endif ASSERT(m_data && m_data != (void*)-1); m_needs_munmap = true; } @@ -207,7 +212,11 @@ Bitmap::~Bitmap() void Bitmap::set_mmap_name(const StringView& name) { ASSERT(m_needs_munmap); +#ifdef __serenity__ ::set_mmap_name(m_data, size_in_bytes(), name.to_string().characters()); +#else + (void)name; +#endif } void Bitmap::fill(Color color) @@ -224,11 +233,13 @@ void Bitmap::set_volatile() ASSERT(m_purgeable); if (m_volatile) return; +#ifdef __serenity__ int rc = madvise(m_data, size_in_bytes(), MADV_SET_VOLATILE); if (rc < 0) { perror("madvise(MADV_SET_VOLATILE)"); ASSERT_NOT_REACHED(); } +#endif m_volatile = true; } @@ -237,11 +248,15 @@ void Bitmap::set_volatile() ASSERT(m_purgeable); if (!m_volatile) return true; +#ifdef __serenity__ int rc = madvise(m_data, size_in_bytes(), MADV_SET_NONVOLATILE); if (rc < 0) { perror("madvise(MADV_SET_NONVOLATILE)"); ASSERT_NOT_REACHED(); } +#else + int rc = 0; +#endif m_volatile = false; return rc == 0; } diff --git a/Libraries/LibGfx/Font.cpp b/Libraries/LibGfx/Font.cpp index 1f882bace3..43ed8fd867 100644 --- a/Libraries/LibGfx/Font.cpp +++ b/Libraries/LibGfx/Font.cpp @@ -213,7 +213,15 @@ RefPtr<Font> Font::load_from_file(const StringView& path) bool Font::write_to_file(const StringView& path) { - int fd = creat_with_path_length(path.characters_without_null_termination(), path.length(), 0644); + int fd; +#ifdef __serenity__ + fd = creat_with_path_length(path.characters_without_null_termination(), path.length(), 0644); +#else + { + String null_terminated_path = path; + fd = creat(null_terminated_path.characters(), 0644); + } +#endif if (fd < 0) { perror("open"); return false; diff --git a/Libraries/LibGfx/GIFLoader.cpp b/Libraries/LibGfx/GIFLoader.cpp index bc5da95537..a7e3f89407 100644 --- a/Libraries/LibGfx/GIFLoader.cpp +++ b/Libraries/LibGfx/GIFLoader.cpp @@ -432,7 +432,7 @@ bool load_gif_frame_descriptors(GIFLoadingContext& context) if (sub_block_length == 0) break; - u8 dummy; + u8 dummy = 0; for (u16 i = 0; i < sub_block_length; ++i) { stream >> dummy; sub_block.append(dummy); diff --git a/Libraries/LibGfx/JPGLoader.cpp b/Libraries/LibGfx/JPGLoader.cpp index f25bf52076..57772534d2 100644 --- a/Libraries/LibGfx/JPGLoader.cpp +++ b/Libraries/LibGfx/JPGLoader.cpp @@ -466,7 +466,7 @@ static inline bool is_valid_marker(const Marker marker) static inline u16 read_be_word(BufferStream& stream) { - u8 tmp1, tmp2; + u8 tmp1 = 0, tmp2 = 0; stream >> tmp1 >> tmp2; return ((u16)tmp1 << 8) | ((u16)tmp2); } @@ -505,6 +505,8 @@ static bool read_start_of_scan(BufferStream& stream, JPGLoadingContext& context) return false; u8 component_count; stream >> component_count; + if (stream.handle_read_failure()) + return false; if (component_count != context.component_count) { dbg() << stream.offset() << String::format(": Unsupported number of components: %i!", component_count); @@ -515,6 +517,8 @@ static bool read_start_of_scan(BufferStream& stream, JPGLoadingContext& context) ComponentSpec* component = nullptr; u8 component_id; stream >> component_id; + if (stream.handle_read_failure()) + return false; component_id += context.has_zero_based_ids ? 1 : 0; if (component_id == context.components[0].id) @@ -530,16 +534,24 @@ static bool read_start_of_scan(BufferStream& stream, JPGLoadingContext& context) u8 table_ids; stream >> table_ids; + if (stream.handle_read_failure()) + return false; component->dc_destination_id = table_ids >> 4; component->ac_destination_id = table_ids & 0x0F; } u8 spectral_selection_start; stream >> spectral_selection_start; + if (stream.handle_read_failure()) + return false; u8 spectral_selection_end; stream >> spectral_selection_end; + if (stream.handle_read_failure()) + return false; u8 successive_approximation; stream >> successive_approximation; + if (stream.handle_read_failure()) + return false; // The three values should be fixed for baseline JPEGs utilizing sequential DCT. if (spectral_selection_start != 0 || spectral_selection_end != 63 || successive_approximation != 0) { dbg() << stream.offset() << ": ERROR! Start of Selection: " << spectral_selection_start @@ -574,6 +586,8 @@ static bool read_huffman_table(BufferStream& stream, JPGLoadingContext& context) HuffmanTableSpec table; u8 table_info; stream >> table_info; + if (stream.handle_read_failure()) + return false; u8 table_type = table_info >> 4; u8 table_destination_id = table_info & 0x0F; if (table_type > 1) { @@ -593,6 +607,8 @@ static bool read_huffman_table(BufferStream& stream, JPGLoadingContext& context) for (int i = 0; i < 16; i++) { u8 count; stream >> count; + if (stream.handle_read_failure()) + return false; total_codes += count; table.code_counts[i] = count; } @@ -601,11 +617,14 @@ static bool read_huffman_table(BufferStream& stream, JPGLoadingContext& context) // Read symbols. Read X bytes, where X is the sum of the counts of codes read in the previous step. for (u32 i = 0; i < total_codes; i++) { - u8 symbol; + u8 symbol = 0; stream >> symbol; table.symbols.append(symbol); } + if (stream.handle_read_failure()) + return false; + if (table_type == 0) context.dc_tables.append(move(table)); else @@ -690,8 +709,10 @@ static bool read_start_of_frame(BufferStream& stream, JPGLoadingContext& context context.has_zero_based_ids = component.id == 0; component.id += context.has_zero_based_ids ? 1 : 0; - u8 subsample_factors; + u8 subsample_factors = 0; stream >> subsample_factors; + if (stream.handle_read_failure()) + return false; component.hsample_factor = subsample_factors >> 4; component.vsample_factor = subsample_factors & 0x0F; @@ -732,6 +753,8 @@ static bool read_quantization_table(BufferStream& stream, JPGLoadingContext& con while (bytes_to_read > 0) { u8 info_byte; stream >> info_byte; + if (stream.handle_read_failure()) + return false; u8 element_unit_hint = info_byte >> 4; if (element_unit_hint > 1) { dbg() << stream.offset() @@ -746,12 +769,15 @@ static bool read_quantization_table(BufferStream& stream, JPGLoadingContext& con u32* table = table_id == 0 ? context.luma_table : context.chroma_table; for (int i = 0; i < 64; i++) { if (element_unit_hint == 0) { - u8 tmp; + u8 tmp = 0; stream >> tmp; table[zigzag_map[i]] = tmp; } else table[zigzag_map[i]] = read_be_word(stream); } + if (stream.handle_read_failure()) + return false; + bytes_to_read -= 1 + (element_unit_hint == 0 ? 64 : 128); } if (bytes_to_read != 0) { @@ -1081,6 +1107,8 @@ static bool scan_huffman_stream(BufferStream& stream, JPGLoadingContext& context u8 last_byte; u8 current_byte; stream >> current_byte; + if (stream.handle_read_failure()) + return false; for (;;) { last_byte = current_byte; diff --git a/Libraries/LibGfx/PNGLoader.cpp b/Libraries/LibGfx/PNGLoader.cpp index eec4fcde36..db0a14e216 100644 --- a/Libraries/LibGfx/PNGLoader.cpp +++ b/Libraries/LibGfx/PNGLoader.cpp @@ -32,13 +32,16 @@ #include <LibGfx/PNGLoader.h> #include <LibM/math.h> #include <fcntl.h> -#include <serenity.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> #include <sys/stat.h> #include <unistd.h> +#ifdef __serenity__ +# include <serenity.h> +#endif + //#define PNG_DEBUG namespace Gfx { @@ -747,7 +750,11 @@ static bool decode_png_bitmap(PNGLoadingContext& context) return false; } context.decompression_buffer_size = destlen; +#ifdef __serenity__ context.decompression_buffer = (u8*)mmap_with_name(nullptr, context.decompression_buffer_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0, "PNG decompression buffer"); +#else + context.decompression_buffer = (u8*)mmap(nullptr, context.decompression_buffer_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); +#endif ret = puff(context.decompression_buffer, &destlen, context.compressed_data.data() + 2, &srclen); if (ret != 0) { diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index 49296acc2d..6111f70645 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -39,9 +39,12 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") endif() file(GLOB AK_SOURCES "../../AK/*.cpp") -file(GLOB LIBCORE_SOURCES "../../Libraries/LibCore/*.cpp") +file(GLOB LIBCORE_SOURCES "../../Libraries/LibCore/*.c*") +file(GLOB LIBGEMINI_SOURCES "../../Libraries/LibGemini/*.cpp") +file(GLOB LIBGFX_SOURCES "../../Libraries/LibGfx/*.cpp") file(GLOB LIBIPC_SOURCES "../../Libraries/LibIPC/*.cpp") file(GLOB LIBLINE_SOURCES "../../Libraries/LibLine/*.cpp") +set(LIBM_SOURCES "../../Libraries/LibM/math.cpp") file(GLOB LIBMARKDOWN_SOURCES "../../Libraries/LibMarkdown/*.cpp") file(GLOB LIBX86_SOURCES "../../Libraries/LibX86/*.cpp") file(GLOB LIBJS_SOURCES "../../Libraries/LibJS/*.cpp") @@ -53,7 +56,7 @@ file(GLOB SHELL_SOURCES "../../Shell/*.cpp") file(GLOB SHELL_TESTS "../../Shell/Tests/*.sh") set(LAGOM_CORE_SOURCES ${AK_SOURCES} ${LIBCORE_SOURCES}) -set(LAGOM_MORE_SOURCES ${LIBIPC_SOURCES} ${LIBLINE_SOURCES} ${LIBJS_SOURCES} ${LIBJS_SUBDIR_SOURCES} ${LIBX86_SOURCES} ${LIBCRYPTO_SOURCES} ${LIBCRYPTO_SUBDIR_SOURCES} ${LIBTLS_SOURCES} ${LIBMARKDOWN_SOURCES}) +set(LAGOM_MORE_SOURCES ${LIBIPC_SOURCES} ${LIBLINE_SOURCES} ${LIBJS_SOURCES} ${LIBJS_SUBDIR_SOURCES} ${LIBX86_SOURCES} ${LIBCRYPTO_SOURCES} ${LIBCRYPTO_SUBDIR_SOURCES} ${LIBTLS_SOURCES} ${LIBMARKDOWN_SOURCES} ${LIBGEMINI_SOURCES} ${LIBGFX_SOURCES}) include_directories (../../) include_directories (../../Libraries/) |