diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..5ace460 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/build-extension.yml b/.github/workflows/build-extension.yml index a29ecd6..596c13a 100644 --- a/.github/workflows/build-extension.yml +++ b/.github/workflows/build-extension.yml @@ -10,6 +10,15 @@ on: required: true cxx: type: string + cache-key: + type: string + required: false + cache-dir: + type: string + required: false + sourcemod-branch: + type: string + required: false upload: type: boolean required: false @@ -22,81 +31,99 @@ on: type: boolean required: false default: false - cache-key: - type: string - required: true - cache-dir: + container: type: string - required: true + required: false jobs: build: - name: Accelerator Extension ${{ inputs.os }}-${{ inputs.cc }} + name: ${{ inputs.os }}-${{ inputs.cc }} runs-on: ${{ inputs.os }} + container: ${{ inputs.container }} env: - SOURCEMOD: ${{ github.workspace }}/${{ inputs.cache-dir }}/sourcemod + CACHE_KEY: ${{ inputs.cache-key }} + CACHE_DIR: ${{ inputs.cache-dir }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: fetch-depth: 0 - submodules: true + submodules: recursive - - name: Retrieve the cache - id: cache - uses: actions/cache@v4 - with: - path: ${{ inputs.cache-dir }} - key: ${{ inputs.cache-key }} - fail-on-cache-miss: true - enableCrossOsArchive: true - - name: Linux dependencies if: startsWith(runner.os, 'Linux') + shell: bash run: | - sudo dpkg --add-architecture i386 - sudo apt-get update - sudo apt-get install -y --no-install-recommends \ - gcc-multilib g++-multilib libstdc++6 lib32stdc++6 \ - libc6-dev libc6-dev-i386 linux-libc-dev \ - linux-libc-dev:i386 lib32z1-dev \ - zlib1g-dev:i386 zlib1g-dev ${{ inputs.cc }} + dpkg --add-architecture i386 + apt-get update + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends --allow-downgrades \ + linux-libc-dev/bullseye linux-libc-dev:i386/bullseye zstd - - name: Select clang compiler + - name: Select compiler if: startsWith(runner.os, 'Linux') + shell: bash run: | echo "CC=${{ inputs.cc }}" >> $GITHUB_ENV echo "CXX=${{ inputs.cxx }}" >> $GITHUB_ENV ${{ inputs.cc }} --version ${{ inputs.cxx }} --version - - uses: actions/setup-python@v5 - name: Setup Python 3.10 + - name: Retrieve the cache + if: ${{ inputs.cache-key != '' }} + uses: actions/cache/restore@v6 with: - python-version: '3.10' + path: ${{ inputs.cache-dir }} + key: ${{ inputs.cache-key }} + fail-on-cache-miss: true + enableCrossOsArchive: true - - name: Install AMBuild + - name: SourceMod checkout + if: ${{ inputs.cache-key == '' && inputs.sourcemod-branch != '' }} + uses: actions/checkout@v7 + with: + repository: alliedmodders/sourcemod + ref: ${{ inputs.sourcemod-branch }} + submodules: recursive + path: sourcemod + fetch-depth: 1 + + - name: Resolve SourceMod path + shell: bash run: | - python -m pip install --upgrade pip setuptools wheel - pip install ./${{ inputs.cache-dir }}/ambuild + if [ -n "$CACHE_KEY" ]; then + SOURCEMOD="$GITHUB_WORKSPACE/$CACHE_DIR/sourcemod" + else + SOURCEMOD="$GITHUB_WORKSPACE/sourcemod" + fi + if [ ! -d "$SOURCEMOD" ]; then + echo "::error::SourceMod not found at $SOURCEMOD, pass either cache-key/cache-dir or sourcemod-branch" + exit 1 + fi + echo "SOURCEMOD=$SOURCEMOD" >> $GITHUB_ENV - - name: Build (Debug) - if: ${{ inputs.debug }} + - name: Install AMBuild + if: ${{ inputs.cache-key != '' || inputs.container == '' }} + shell: bash run: | - mkdir -p build && cd build - python ../configure.py --enable-debug - ambuild + if [ -z "${{ inputs.container }}" ]; then + python3 -m pip install --upgrade pip setuptools wheel + fi + if [ -n "$CACHE_KEY" ]; then + python3 -m pip install --force-reinstall --no-deps "./$CACHE_DIR/ambuild" + else + python3 -m pip install git+https://github.com/alliedmodders/ambuild + fi - - name: Build (Release) - if: not ${{ inputs.debug }} + - name: Build + shell: bash run: | mkdir -p build && cd build - python ../configure.py --enable-optimize + python3 ../configure.py ${{ inputs.debug && '--enable-debug' || '--enable-optimize' }} ambuild - name: Upload package if: ${{ inputs.upload }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: ${{ inputs.upload-artifact-name }} - path: build/package \ No newline at end of file + path: build/package diff --git a/.github/workflows/cache.yml b/.github/workflows/cache.yml index 0bd3c0f..102d560 100644 --- a/.github/workflows/cache.yml +++ b/.github/workflows/cache.yml @@ -10,48 +10,42 @@ on: jobs: cache: name: Create cache - runs-on: 'ubuntu-latest' + runs-on: ubuntu-latest outputs: key: ${{ steps.cache-key.outputs.key }} env: - SOURCEMOD_REF: 'e0e018c5ebcd11df9bab91b43d40bf148805c684' - AMBUILD_REF: '2d4620da4cdaf89cf25afc3577f920e6138ae7cd' + SOURCEMOD_REF: '2e229b111534b1be007dc3bd9acfcf2fc472e893' + AMBUILD_REF: '9ed1920068c8a767ae78022102abc93a6822eaad' steps: - - uses: actions/checkout@v4 - - name: Create cache key - run: | - echo "${{ env.SOURCEMOD_REF }}" >> cache-key - echo "${{ env.AMBUILD_REF }}" >> cache-key - - - name: Output cache key id: cache-key - run: | - ls -a - echo "key=cache-${{ hashFiles('cache-key') }}" >> $GITHUB_OUTPUT + run: echo "key=sourcemod-${SOURCEMOD_REF}-ambuild-${AMBUILD_REF}" >> $GITHUB_OUTPUT - name: Retrieve the cache id: cache - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: .cache key: ${{ steps.cache-key.outputs.key }} enableCrossOsArchive: true + lookup-only: true - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 if: ${{ !steps.cache.outputs.cache-hit }} name: SourceMod checkout with: repository: alliedmodders/sourcemod ref: ${{ env.SOURCEMOD_REF }} - submodules: true + submodules: recursive path: .cache/sourcemod + persist-credentials: false - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 if: ${{ !steps.cache.outputs.cache-hit }} name: AMBuild checkout with: repository: alliedmodders/ambuild ref: ${{ env.AMBUILD_REF }} - path: .cache/ambuild \ No newline at end of file + path: .cache/ambuild + persist-credentials: false diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58dad97..c3a479c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,45 +2,61 @@ name: CI on: workflow_dispatch: workflow_call: - inputs: - release: - type: boolean - required: true - default: false jobs: cache: uses: ./.github/workflows/cache.yml - build-options: - runs-on: ubuntu-latest - outputs: - exclude: ${{ steps.set.outputs.exclude }} - steps: - - id: set - run: | - echo "exclude=[${{ inputs.release && '{"runners": { "upload": false } }' || '' }}]" >> $GITHUB_OUTPUT - - build: - name: Build - needs: [ cache, build-options ] - + sm112: + name: SM 1.12 + needs: [ cache ] strategy: fail-fast: false matrix: - runners: [ - { os: ubuntu-22.04, cc: clang, cxx: clang++, upload: true, upload-artifact-name: accelerator_linux }, - { os: ubuntu-latest, cc: clang, cxx: clang++, upload: false }, - { os: windows-latest, cc: msvc, cxx: msvc, upload: true, upload-artifact-name: accelerator_windows } - ] - exclude: ${{ fromJson(needs.build-options.outputs.exclude) }} - + include: + - os: ubuntu-latest + cc: clang-22 + cxx: clang++-22 + container: 'ghcr.io/alliedmodders/build-containers/debian11-clang22:latest' + artifact: accelerator_linux + - os: windows-latest + cc: msvc + cxx: msvc + container: '' + artifact: accelerator_windows uses: ./.github/workflows/build-extension.yml with: - os: ${{ matrix.runners.os }} - cc: ${{ matrix.runners.cc }} - cxx: ${{ matrix.runners.cxx }} - upload: ${{ matrix.runners.upload }} - upload-artifact-name: ${{ matrix.runners.upload-artifact-name }} + os: ${{ matrix.os }} + cc: ${{ matrix.cc }} + cxx: ${{ matrix.cxx }} + container: ${{ matrix.container }} cache-key: ${{ needs.cache.outputs.key }} - cache-dir: ${{ needs.cache.outputs.dir }} \ No newline at end of file + cache-dir: ${{ needs.cache.outputs.dir }} + upload: true + upload-artifact-name: ${{ matrix.artifact }} + + sm113: + name: SM 1.13 + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + cc: clang-22 + cxx: clang++-22 + container: 'ghcr.io/alliedmodders/build-containers/debian11-clang22:latest' + artifact: accelerator_sm113_linux + - os: windows-latest + cc: msvc + cxx: msvc + container: '' + artifact: accelerator_sm113_windows + uses: ./.github/workflows/build-extension.yml + with: + os: ${{ matrix.os }} + cc: ${{ matrix.cc }} + cxx: ${{ matrix.cxx }} + container: ${{ matrix.container }} + sourcemod-branch: 'master' + upload: true + upload-artifact-name: ${{ matrix.artifact }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index e2cdce8..05bff7b 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -8,5 +8,3 @@ on: jobs: main-ci: uses: ./.github/workflows/ci.yml - with: - release: false diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d725a0f..e964a5f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,33 +8,31 @@ on: jobs: main-ci: uses: ./.github/workflows/ci.yml - with: - release: true release: - permissions: write-all + permissions: + contents: read runs-on: ubuntu-latest needs: [ main-ci ] env: PROJECT: 'accelerator' + UPLOAD_PASSWORD: ${{ secrets.UPLOAD_PASSWORD }} steps: - - run: sudo apt-get install -y tree - - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 name: Repository checkout with: fetch-depth: 0 path: repository - + - name: Download Linux release - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v8 with: name: accelerator_linux path: linux - name: Download Windows release - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v8 with: name: accelerator_windows path: windows @@ -55,10 +53,11 @@ jobs: echo "LINUX_ZIP=${LINUX_ZIP}" >> $GITHUB_ENV - name: Upload release + if: env.UPLOAD_PASSWORD != '' shell: bash run: | echo "Begin upload for branch (${{ github.ref_name }})" - AUTHORIZATION="$(echo -n 'builds:${{ secrets.UPLOAD_PASSWORD }}' | base64)" + AUTHORIZATION="$(echo -n "builds:${UPLOAD_PASSWORD}" | base64)" echo "::add-mask::${AUTHORIZATION}" echo "Uploading ${{ env.WINDOWS_ZIP }}" @@ -74,3 +73,17 @@ jobs: exit 1 fi echo "Upload successful!" + + - name: Upload Windows artifact + if: ${{ !cancelled() }} + uses: actions/upload-artifact@v7 + with: + path: ${{ env.WINDOWS_ZIP }} + archive: false + + - name: Upload Linux artifact + if: ${{ !cancelled() }} + uses: actions/upload-artifact@v7 + with: + path: ${{ env.LINUX_ZIP }} + archive: false diff --git a/AMBuildScript b/AMBuildScript index b5f4568..f4cb5fe 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -111,7 +111,7 @@ class AcceleratorConfig(object): ] cxx.cxxflags += [ - '-std=c++17', + '-std=c++20', '-fno-threadsafe-statics', '-Wno-non-virtual-dtor', '-Wno-overloaded-virtual', @@ -128,7 +128,7 @@ class AcceleratorConfig(object): cxx.cxxflags += [ '/EHsc', - '/std:c++17' + '/std:c++20' ] return @@ -158,7 +158,9 @@ class AcceleratorConfig(object): os.path.join(self.sm_root, 'public', 'extensions'), os.path.join(self.sm_root, 'public', 'amtl', 'amtl'), os.path.join(self.sm_root, 'public', 'amtl'), - os.path.join(self.sm_root, 'sourcepawn', 'include') + os.path.join(self.sm_root, 'sourcepawn', 'include'), + os.path.join(self.sm_root, 'sourcepawn', 'vm'), + os.path.join(self.sm_root, 'sourcepawn') ] def link_libz(self, compiler, context): diff --git a/extension/extension.cpp b/extension/extension.cpp index d4a8f75..a5ee099 100644 --- a/extension/extension.cpp +++ b/extension/extension.cpp @@ -25,6 +25,10 @@ #include +#if SMINTERFACE_EXTENSIONAPI_VERSION >= 9 +#include +#endif + #include #include "MemoryDownloader.h" #include "forwards.h" @@ -1085,24 +1089,16 @@ class UploadThread: public IThread } } uploadThread; -class SourcePawnNotifyThread : public IThread +void Accelerator::NotifyIfDoneUploading() { -public: - - void RunThread(IThreadHandle* pHandle) { - for (;;) { - // Wait until OnMapStart is called once, this should be enough delay to make sure plugins are loaded. - if (g_accelerator.IsMapStarted() && g_accelerator.IsDoneUploading()) { - extforwards::CallOnDoneUploadingForward(); - break; - } - } + if (!IsMapStarted() || !IsDoneUploading()) { + return; } - void OnTerminate(IThreadHandle* pHandle, bool cancel) { + if (!m_notified.exchange(true)) { + extforwards::CallOnDoneUploadingForward(); } - -} spNotifyThread; +} class VFuncEmptyClass {}; @@ -1142,7 +1138,7 @@ const char *GetCmdLine() } Accelerator::Accelerator() : - m_doneuploading(false), m_maphasstarted(false) + m_doneuploading(false), m_maphasstarted(false), m_notified(false) { } @@ -1171,7 +1167,6 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late) strncpy(crashGameDirectory, g_pSM->GetGameFolderName(), sizeof(crashGameDirectory) - 1); threader->MakeThread(&uploadThread); - threader->MakeThread(&spNotifyThread); // This thread waits for accelator to be done uploading and for the first OnMapStart call, then fires a SourceMod forward do { char gameconfigError[256]; @@ -1234,6 +1229,9 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late) #error Bad platform. #endif +#if SMINTERFACE_EXTENSIONAPI_VERSION < 9 + // 1.13 links the SourcePawn VM into sourcemod.logic and dropped ISourcePawnFactory, + // so there is no sourcepawn.jit library left to load here. do { char spJitPath[512]; g_pSM->BuildPath(Path_SM, spJitPath, sizeof(spJitPath), "bin/" PLATFORM_ARCH_FOLDER "sourcepawn.jit.x86." PLATFORM_LIB_EXT); @@ -1253,7 +1251,7 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late) ISourcePawnFactory *spFactory = factoryFn(0x0207); if (!spFactory) { - smutils->LogMessage(myself, "WARNING: SourcePawn library is out of date: Failed to get version 2.7", 0x0207); + smutils->LogMessage(myself, "WARNING: SourcePawn library is out of date: Failed to get version 2.7"); break; } @@ -1269,8 +1267,9 @@ bool Accelerator::SDK_OnLoad(char *error, size_t maxlength, bool late) break; } - strncpy(crashSourceModVersion, spEngine2->GetVersionString(), sizeof(crashSourceModVersion)); + strncpy(crashSourceModVersion, spEngine2->GetVersionString(), sizeof(crashSourceModVersion) - 1); } while(false); +#endif plsys->AddPluginsListener(this); @@ -1376,12 +1375,16 @@ void Accelerator::SDK_OnAllLoaded() m_natives.push_back({ nullptr, nullptr }); // SM requires this to signal the end of the native info array sharesys->AddNatives(myself, m_natives.data()); + + NotifyIfDoneUploading(); } void Accelerator::OnCoreMapStart(edict_t *pEdictList, int edictCount, int clientMax) { strncpy(crashMap, gamehelpers->GetCurrentMap(), sizeof(crashMap) - 1); m_maphasstarted.store(true); + + NotifyIfDoneUploading(); } /* 010 Editor Template @@ -1476,6 +1479,16 @@ void Accelerator::OnPluginLoaded(IPlugin *plugin) return; } +#if SMINTERFACE_EXTENSIONAPI_VERSION >= 9 + // 1.13 moved publics enumeration onto sp::BaseRuntime. + sp::BaseRuntime *publics = runtime->GetBaseRuntime(); + if (!publics) { + return; + } +#else + IPluginRuntime *publics = runtime; +#endif + const char *filename = plugin->GetFilename(); size_t filenameSize = strlen(filename) + 1; @@ -1484,13 +1497,13 @@ void Accelerator::OnPluginLoaded(IPlugin *plugin) size += sizeof(void *); // GetBaseContext size += filenameSize; - uint32_t count = runtime->GetPublicsNum(); + uint32_t count = publics->GetPublicsNum(); size += sizeof(uint32_t); // count size += count * sizeof(uint32_t); // pubinfo->code_offs for (uint32_t i = 0; i < count; ++i) { sp_public_t *pubinfo; - runtime->GetPublicByIndex(i, &pubinfo); + publics->GetPublicByIndex(i, &pubinfo); size += strlen(pubinfo->name) + 1; } @@ -1512,7 +1525,7 @@ void Accelerator::OnPluginLoaded(IPlugin *plugin) for (uint32_t i = 0; i < count; ++i) { sp_public_t *pubinfo; - runtime->GetPublicByIndex(i, &pubinfo); + publics->GetPublicByIndex(i, &pubinfo); memcpy(cursor, &pubinfo->code_offs, sizeof(uint32_t)); cursor += sizeof(uint32_t); diff --git a/extension/extension.h b/extension/extension.h index 0412a7c..17d6854 100644 --- a/extension/extension.h +++ b/extension/extension.h @@ -115,7 +115,7 @@ class Accelerator : public SDKExtension, IPluginsListener /** * @brief Signals the extension that uploading is done. */ - void MarkAsDoneUploading() { m_doneuploading.store(true); } + void MarkAsDoneUploading() { m_doneuploading.store(true); NotifyIfDoneUploading(); } /** * @brief Is Accelerator done uploading crashes. * @return Returns true if yes, false otherwise. @@ -128,11 +128,17 @@ class Accelerator : public SDKExtension, IPluginsListener bool IsMapStarted() const { return m_maphasstarted.load(); } private: + /** + * @brief Fires the done uploading forward once uploading has finished and a map has started. + */ + void NotifyIfDoneUploading(); + std::vector m_uploadedcrashes; // Vector of uploaded crashes std::vector m_natives; // Vector of SourcePawn natives mutable std::mutex m_uploadedcrashes_mutex; // mutex for accessing the m_uploadedcrashes vector std::atomic_bool m_doneuploading; // Signals that Accelerator is done uploading crashes. std::atomic_bool m_maphasstarted; // Signals that OnMapStart has been called at least once. + std::atomic_bool m_notified; // Signals that the done uploading forward has been queued. }; // Expose the extension singleton. diff --git a/patches/0001-Ignore-invalid-modules-rather-than-bailing-on-the-en.patch b/patches/0001-Ignore-invalid-modules-rather-than-bailing-on-the-en.patch index 60f3220..d5f29f8 100644 --- a/patches/0001-Ignore-invalid-modules-rather-than-bailing-on-the-en.patch +++ b/patches/0001-Ignore-invalid-modules-rather-than-bailing-on-the-en.patch @@ -1,7 +1,7 @@ From 1f35257db226d6d0189cff0832a97cccc639c91a Mon Sep 17 00:00:00 2001 From: Asher Baker Date: Sun, 13 Jan 2019 12:34:45 +0000 -Subject: [PATCH 1/5] Ignore invalid modules rather than bailing on the entire +Subject: [PATCH 1/3] Ignore invalid modules rather than bailing on the entire module list --- @@ -9,10 +9,10 @@ Subject: [PATCH 1/5] Ignore invalid modules rather than bailing on the entire 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc -index 775f117c..066fd36f 100644 +index 76310090..ca864968 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc -@@ -3198,7 +3198,7 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { +@@ -3197,7 +3197,7 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { BPLOG(ERROR) << "MinidumpModuleList could not read required module " "auxiliary data for module " << module_index << "/" << module_count; @@ -21,7 +21,7 @@ index 775f117c..066fd36f 100644 } // It is safe to use module->code_file() after successfully calling -@@ -3210,7 +3210,14 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { +@@ -3209,7 +3209,14 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { BPLOG(ERROR) << "MinidumpModuleList found bad base address for module " << module_index << "/" << module_count << ", " << module.code_file(); @@ -37,7 +37,7 @@ index 775f117c..066fd36f 100644 } // Some minidumps have additional modules in the list that are duplicates. -@@ -3237,7 +3244,7 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { +@@ -3236,7 +3243,7 @@ bool MinidumpModuleList::Read(uint32_t expected_size) { << module_index << "/" << module_count << ", " << module.code_file() << ", " << HexString(base_address) << "+" << HexString(module_size); diff --git a/patches/0002-Write-FUNC-records-instead-of-PUBLIC-for-ELF-symbols.patch b/patches/0002-Write-FUNC-records-instead-of-PUBLIC-for-ELF-symbols.patch index 3218713..f6d234f 100644 --- a/patches/0002-Write-FUNC-records-instead-of-PUBLIC-for-ELF-symbols.patch +++ b/patches/0002-Write-FUNC-records-instead-of-PUBLIC-for-ELF-symbols.patch @@ -1,15 +1,15 @@ From 8aaf6e84a6704eb538f68a3e6fb6c3a8c93f1d8d Mon Sep 17 00:00:00 2001 From: Asher Baker Date: Sun, 13 Jan 2019 12:35:05 +0000 -Subject: [PATCH 2/5] Write FUNC records instead of PUBLIC for ELF symbols with +Subject: [PATCH 2/3] Write FUNC records instead of PUBLIC for ELF symbols with sizes - --- - src/common/linux/elf_symbols_to_module.cc | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) +--- + src/common/linux/elf_symbols_to_module.cc | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/common/linux/elf_symbols_to_module.cc b/src/common/linux/elf_symbols_to_module.cc -index 70d50f89..f21460bf 100644 +index 2e5c4eeb..2a409bb5 100644 --- a/src/common/linux/elf_symbols_to_module.cc +++ b/src/common/linux/elf_symbols_to_module.cc @@ -164,19 +164,28 @@ bool ELFSymbolsToModule(const uint8_t* symtab_section, @@ -31,17 +31,18 @@ index 70d50f89..f21460bf 100644 free(demangled); } #endif -+#if 1 +- module->AddExtern(std::move(ext)); + if (iterator->size) { + Module::Function *fun = new Module::Function(module->AddStringToPool(name), iterator->value); + fun->ranges.push_back(Module::Range(iterator->value, iterator->size)); -+ module->AddFunction(fun); ++ if (!module->AddFunction(fun)) { ++ delete fun; ++ } ++ } else { ++ auto ext = std::make_unique(iterator->value); ++ ext->name = name; ++ module->AddExtern(std::move(ext)); + } -+#else -+ Module::Extern *ext = new Module::Extern(iterator->value); -+ ext->name = name; - module->AddExtern(std::move(ext)); -+#endif } ++iterator; } diff --git a/patches/0003-Include-the-kernel-s-a.out.h-instead-of-glibc-s.patch b/patches/0003-Include-the-kernel-s-a.out.h-instead-of-glibc-s.patch new file mode 100644 index 0000000..9f09e45 --- /dev/null +++ b/patches/0003-Include-the-kernel-s-a.out.h-instead-of-glibc-s.patch @@ -0,0 +1,21 @@ +From: Mikusch <25514044+Mikusch@users.noreply.github.com> +Date: Sat, 5 Sep 2026 23:41:05 +0200 +Subject: [PATCH 3/3] Include the kernel's a.out.h instead of glibc's + +--- + src/common/stabs_reader.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/common/stabs_reader.h b/src/common/stabs_reader.h +index c8b297b5..fd452969 100644 +--- a/src/common/stabs_reader.h ++++ b/src/common/stabs_reader.h +@@ -52,7 +52,7 @@ + #ifdef HAVE_MACH_O_NLIST_H + #include + #elif defined(HAVE_A_OUT_H) +-#include ++#include + #endif + + #include diff --git a/patches/0003-Support-compilation-on-VS-2015.patch b/patches/0003-Support-compilation-on-VS-2015.patch deleted file mode 100644 index edbed52..0000000 --- a/patches/0003-Support-compilation-on-VS-2015.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 2f217812634d5e6c56f0cf9e7a4c9b7fb390e954 Mon Sep 17 00:00:00 2001 -From: patches -Date: Sat, 20 Jul 2019 15:52:37 +0100 -Subject: [PATCH 3/5] Support compilation on VS 2015 - ---- - src/common/windows/pe_util.cc | 1 + - src/common/windows/pe_util.h | 2 +- - src/tools/windows/dump_syms/dump_syms.cc | 1 + - 3 files changed, 3 insertions(+), 1 deletion(-) - - -diff --git a/src/common/windows/pe_util.h b/src/common/windows/pe_util.h -index 6c6b364f..80aba5e5 100644 ---- a/src/common/windows/pe_util.h -+++ b/src/common/windows/pe_util.h -@@ -59,7 +59,7 @@ wstring GenerateDebugIdentifier(DWORD age, DWORD signature); - - // Converts |machine| enum value to the corresponding string used by Breakpad. - // The enum is IMAGE_FILE_MACHINE_*, contained in winnt.h. --constexpr const wchar_t* FileHeaderMachineToCpuString(WORD machine) { -+static inline const wchar_t* FileHeaderMachineToCpuString(WORD machine) { - switch (machine) { - case IMAGE_FILE_MACHINE_I386: { - return L"x86"; diff --git a/patches/0004-Fix-Linux-a-out-include.patch b/patches/0004-Fix-Linux-a-out-include.patch deleted file mode 100644 index 8dab0fd..0000000 --- a/patches/0004-Fix-Linux-a-out-include.patch +++ /dev/null @@ -1,38 +0,0 @@ -Subject: [PATCH 4/5] Fixes path to a.out.h file - -diff --git a/configure b/configure -index 3442e796..3e7c321c 100755 ---- a/configure -+++ b/configure -@@ -7532,11 +7532,16 @@ then : - printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h - - fi --ac_fn_c_check_header_compile "$LINENO" "a.out.h" "ac_cv_header_a_out_h" "$ac_includes_default" -+ac_fn_c_check_header_compile "$LINENO" "linux/a.out.h" "ac_cv_header_a_out_h" "$ac_includes_default" - if test "x$ac_cv_header_a_out_h" = xyes - then : - printf "%s\n" "#define HAVE_A_OUT_H 1" >>confdefs.h -- -+else -+ ac_fn_c_check_header_compile "$LINENO" "a.out.h" "ac_cv_header_a_out_h" "$ac_includes_default" -+ if test "x$ac_cv_header_a_out_h" = xyes -+ then : -+ printf "%s\n" "#define HAVE_A_OUT_H_EX 1" >>confdefs.h -+ fi - fi - ac_fn_c_check_header_compile "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default" - if test "x$ac_cv_header_sys_mman_h" = xyes -diff --git a/src/common/stabs_reader.h b/src/common/stabs_reader.h -index 655683f1..1e6a76b8 100644 ---- a/src/common/stabs_reader.h -+++ b/src/common/stabs_reader.h -@@ -52,6 +52,8 @@ - #ifdef HAVE_MACH_O_NLIST_H - #include - #elif defined(HAVE_A_OUT_H) -+#include -+#elif defined(HAVE_A_OUT_H_EX) - #include - #endif - diff --git a/patches/0005-Add-LSS.patch b/patches/0005-Add-LSS.patch deleted file mode 100644 index 953fda8..0000000 --- a/patches/0005-Add-LSS.patch +++ /dev/null @@ -1,5342 +0,0 @@ -Subject: [PATCH 5/5] Insert the linux_syscall_support.h file as a patch - -diff --git a/src/third_party/lss/linux_syscall_support.h b/src/third_party/lss/linux_syscall_support.h -new file mode 100644 -index 00000000..8d09f6b0 ---- /dev/null -+++ b/src/third_party/lss/linux_syscall_support.h -@@ -0,0 +1,5333 @@ -+/* Copyright 2005-2011 Google LLC -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are -+ * met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above -+ * copyright notice, this list of conditions and the following disclaimer -+ * in the documentation and/or other materials provided with the -+ * distribution. -+ * * Neither the name of Google LLC nor the names of its -+ * contributors may be used to endorse or promote products derived from -+ * this software without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * --- -+ * Author: Markus Gutschke -+ */ -+ -+/* This file includes Linux-specific support functions common to the -+ * coredumper and the thread lister; primarily, this is a collection -+ * of direct system calls, and a couple of symbols missing from -+ * standard header files. -+ * There are a few options that the including file can set to control -+ * the behavior of this file: -+ * -+ * SYS_CPLUSPLUS: -+ * The entire header file will normally be wrapped in 'extern "C" { }", -+ * making it suitable for compilation as both C and C++ source. If you -+ * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit -+ * the wrapping. N.B. doing so will suppress inclusion of all prerequisite -+ * system header files, too. It is the caller's responsibility to provide -+ * the necessary definitions. -+ * -+ * SYS_ERRNO: -+ * All system calls will update "errno" unless overridden by setting the -+ * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be -+ * an l-value. -+ * -+ * SYS_INLINE: -+ * New symbols will be defined "static inline", unless overridden by -+ * the SYS_INLINE macro. -+ * -+ * SYS_LINUX_SYSCALL_SUPPORT_H -+ * This macro is used to avoid multiple inclusions of this header file. -+ * If you need to include this file more than once, make sure to -+ * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion. -+ * -+ * SYS_PREFIX: -+ * New system calls will have a prefix of "sys_" unless overridden by -+ * the SYS_PREFIX macro. Valid values for this macro are [0..9] which -+ * results in prefixes "sys[0..9]_". It is also possible to set this -+ * macro to -1, which avoids all prefixes. -+ * -+ * SYS_SYSCALL_ENTRYPOINT: -+ * Some applications (such as sandboxes that filter system calls), need -+ * to be able to run custom-code each time a system call is made. If this -+ * macro is defined, it expands to the name of a "common" symbol. If -+ * this symbol is assigned a non-NULL pointer value, it is used as the -+ * address of the system call entrypoint. -+ * A pointer to this symbol can be obtained by calling -+ * get_syscall_entrypoint() -+ * -+ * This file defines a few internal symbols that all start with "LSS_". -+ * Do not access these symbols from outside this file. They are not part -+ * of the supported API. -+ */ -+#ifndef SYS_LINUX_SYSCALL_SUPPORT_H -+#define SYS_LINUX_SYSCALL_SUPPORT_H -+ -+/* We currently only support x86-32, x86-64, ARM, MIPS, PPC, s390 and s390x -+ * on Linux. -+ * Porting to other related platforms should not be difficult. -+ */ -+#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \ -+ defined(__mips__) || defined(__PPC__) || defined(__ARM_EABI__) || \ -+ defined(__aarch64__) || defined(__s390__) || defined(__e2k__) || \ -+ (defined(__riscv) && __riscv_xlen == 64) || defined(__loongarch_lp64)) \ -+ && (defined(__linux) || defined(__ANDROID__)) -+ -+#ifndef SYS_CPLUSPLUS -+#ifdef __cplusplus -+/* Some system header files in older versions of gcc neglect to properly -+ * handle being included from C++. As it appears to be harmless to have -+ * multiple nested 'extern "C"' blocks, just add another one here. -+ */ -+extern "C" { -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __mips__ -+/* Include definitions of the ABI currently in use. */ -+#ifdef __ANDROID__ -+/* Android doesn't have sgidefs.h, but does have asm/sgidefs.h, -+ * which has the definitions we need. -+ */ -+#include -+#else -+#include -+#endif -+#endif -+#endif -+ -+/* Some libcs, for example Android NDK and musl, #define these -+ * macros as aliases to their non-64 counterparts. To avoid naming -+ * conflict, remove them. -+ * -+ * These are restored by the corresponding #pragma pop_macro near -+ * the end of this file. -+ */ -+#pragma push_macro("stat64") -+#pragma push_macro("fstat64") -+#pragma push_macro("lstat64") -+#pragma push_macro("pread64") -+#pragma push_macro("pwrite64") -+#pragma push_macro("getdents64") -+#undef stat64 -+#undef fstat64 -+#undef lstat64 -+#undef pread64 -+#undef pwrite64 -+#undef getdents64 -+ -+#if defined(__ANDROID__) && defined(__x86_64__) -+// A number of x86_64 syscalls are blocked by seccomp on recent Android; -+// undefine them so that modern alternatives will be used instead where -+// possible. -+// The alternative syscalls have been sanity checked against linux-3.4+; -+// older versions might not work. -+# undef __NR_getdents -+# undef __NR_dup2 -+# undef __NR_fork -+# undef __NR_getpgrp -+# undef __NR_open -+# undef __NR_poll -+# undef __NR_readlink -+# undef __NR_stat -+# undef __NR_unlink -+# undef __NR_pipe -+#endif -+ -+#if defined(__ANDROID__) -+// waitpid is blocked by seccomp on all architectures on recent Android. -+# undef __NR_waitpid -+#endif -+ -+/* As glibc often provides subtly incompatible data structures (and implicit -+ * wrapper functions that convert them), we provide our own kernel data -+ * structures for use by the system calls. -+ * These structures have been developed by using Linux 2.6.23 headers for -+ * reference. Note though, we do not care about exact API compatibility -+ * with the kernel, and in fact the kernel often does not have a single -+ * API that works across architectures. Instead, we try to mimic the glibc -+ * API where reasonable, and only guarantee ABI compatibility with the -+ * kernel headers. -+ * Most notably, here are a few changes that were made to the structures -+ * defined by kernel headers: -+ * -+ * - we only define structures, but not symbolic names for kernel data -+ * types. For the latter, we directly use the native C datatype -+ * (i.e. "unsigned" instead of "mode_t"). -+ * - in a few cases, it is possible to define identical structures for -+ * both 32bit (e.g. i386) and 64bit (e.g. x86-64) platforms by -+ * standardizing on the 64bit version of the data types. In particular, -+ * this means that we use "unsigned" where the 32bit headers say -+ * "unsigned long". -+ * - overall, we try to minimize the number of cases where we need to -+ * conditionally define different structures. -+ * - the "struct kernel_sigaction" class of structures have been -+ * modified to more closely mimic glibc's API by introducing an -+ * anonymous union for the function pointer. -+ * - a small number of field names had to have an underscore appended to -+ * them, because glibc defines a global macro by the same name. -+ */ -+ -+/* include/linux/dirent.h */ -+struct kernel_dirent64 { -+ unsigned long long d_ino; -+ long long d_off; -+ unsigned short d_reclen; -+ unsigned char d_type; -+ char d_name[256]; -+}; -+ -+/* include/linux/dirent.h */ -+#if !defined(__NR_getdents) -+// when getdents is not available, getdents64 is used for both. -+#define kernel_dirent kernel_dirent64 -+#else -+struct kernel_dirent { -+ long d_ino; -+ long d_off; -+ unsigned short d_reclen; -+ char d_name[256]; -+}; -+#endif -+ -+/* include/linux/uio.h */ -+struct kernel_iovec { -+ void *iov_base; -+ unsigned long iov_len; -+}; -+ -+/* include/linux/socket.h */ -+struct kernel_msghdr { -+ void *msg_name; -+ int msg_namelen; -+ struct kernel_iovec*msg_iov; -+ unsigned long msg_iovlen; -+ void *msg_control; -+ unsigned long msg_controllen; -+ unsigned msg_flags; -+}; -+ -+/* include/asm-generic/poll.h */ -+struct kernel_pollfd { -+ int fd; -+ short events; -+ short revents; -+}; -+ -+/* include/linux/resource.h */ -+struct kernel_rlimit { -+ unsigned long rlim_cur; -+ unsigned long rlim_max; -+}; -+ -+/* include/linux/time.h */ -+struct kernel_timespec { -+ long tv_sec; -+ long tv_nsec; -+}; -+ -+/* include/linux/time.h */ -+struct kernel_timeval { -+ long tv_sec; -+ long tv_usec; -+}; -+ -+/* include/linux/time.h */ -+struct kernel_itimerval { -+ struct kernel_timeval it_interval; -+ struct kernel_timeval it_value; -+}; -+ -+/* include/linux/resource.h */ -+struct kernel_rusage { -+ struct kernel_timeval ru_utime; -+ struct kernel_timeval ru_stime; -+ long ru_maxrss; -+ long ru_ixrss; -+ long ru_idrss; -+ long ru_isrss; -+ long ru_minflt; -+ long ru_majflt; -+ long ru_nswap; -+ long ru_inblock; -+ long ru_oublock; -+ long ru_msgsnd; -+ long ru_msgrcv; -+ long ru_nsignals; -+ long ru_nvcsw; -+ long ru_nivcsw; -+}; -+ -+#if defined(__i386__) || defined(__ARM_EABI__) || defined(__ARM_ARCH_3__) \ -+ || defined(__PPC__) || (defined(__s390__) && !defined(__s390x__)) \ -+ || defined(__e2k__) -+ -+/* include/asm-{arm,i386,mips,ppc}/signal.h */ -+struct kernel_old_sigaction { -+ union { -+ void (*sa_handler_)(int); -+ void (*sa_sigaction_)(int, siginfo_t *, void *); -+ }; -+ unsigned long sa_mask; -+ unsigned long sa_flags; -+ void (*sa_restorer)(void); -+} __attribute__((packed,aligned(4))); -+#elif (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) -+ #define kernel_old_sigaction kernel_sigaction -+#elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64) -+ // No kernel_old_sigaction defined for arm64 riscv and loongarch64. -+#endif -+ -+/* Some kernel functions (e.g. sigaction() in 2.6.23) require that the -+ * exactly match the size of the signal set, even though the API was -+ * intended to be extensible. We define our own KERNEL_NSIG to deal with -+ * this. -+ * Please note that glibc provides signals [1.._NSIG-1], whereas the -+ * kernel (and this header) provides the range [1..KERNEL_NSIG]. The -+ * actual number of signals is obviously the same, but the constants -+ * differ by one. -+ */ -+#ifdef __mips__ -+#define KERNEL_NSIG 128 -+#else -+#define KERNEL_NSIG 64 -+#endif -+ -+/* include/asm-{arm,aarch64,i386,mips,x86_64}/signal.h */ -+struct kernel_sigset_t { -+ unsigned long sig[(KERNEL_NSIG + 8*sizeof(unsigned long) - 1)/ -+ (8*sizeof(unsigned long))]; -+}; -+ -+/* include/asm-{arm,i386,mips,x86_64,ppc}/signal.h */ -+struct kernel_sigaction { -+#ifdef __mips__ -+ unsigned long sa_flags; -+ union { -+ void (*sa_handler_)(int); -+ void (*sa_sigaction_)(int, siginfo_t *, void *); -+ }; -+ struct kernel_sigset_t sa_mask; -+#else -+ union { -+ void (*sa_handler_)(int); -+ void (*sa_sigaction_)(int, siginfo_t *, void *); -+ }; -+ unsigned long sa_flags; -+#if !defined(__riscv) && !defined(__loongarch_lp64) -+ void (*sa_restorer)(void); -+#endif -+ struct kernel_sigset_t sa_mask; -+#endif -+}; -+ -+/* include/linux/socket.h */ -+struct kernel_sockaddr { -+ unsigned short sa_family; -+ char sa_data[14]; -+}; -+ -+/* include/asm-{arm,aarch64,i386,mips,ppc,s390}/stat.h */ -+#ifdef __mips__ -+#if _MIPS_SIM == _MIPS_SIM_ABI64 -+typedef unsigned long long kernel_blkcnt_t; -+typedef unsigned kernel_blksize_t; -+typedef unsigned kernel_dev_t; -+typedef unsigned kernel_gid_t; -+typedef unsigned long long kernel_ino_t; -+typedef unsigned kernel_mode_t; -+typedef unsigned kernel_nlink_t; -+typedef long long kernel_off_t; -+typedef unsigned kernel_time_t; -+typedef unsigned kernel_uid_t; -+struct kernel_stat { -+#else -+struct kernel_stat64 { -+#endif -+ unsigned st_dev; -+ unsigned __pad0[3]; -+ unsigned long long st_ino; -+ unsigned st_mode; -+ unsigned st_nlink; -+ unsigned st_uid; -+ unsigned st_gid; -+ unsigned st_rdev; -+ unsigned __pad1[3]; -+ long long st_size; -+ unsigned st_atime_; -+ unsigned st_atime_nsec_; -+ unsigned st_mtime_; -+ unsigned st_mtime_nsec_; -+ unsigned st_ctime_; -+ unsigned st_ctime_nsec_; -+ unsigned st_blksize; -+ unsigned __pad2; -+ unsigned long long st_blocks; -+}; -+#elif defined __PPC__ -+struct kernel_stat64 { -+ unsigned long long st_dev; -+ unsigned long long st_ino; -+ unsigned st_mode; -+ unsigned st_nlink; -+ unsigned st_uid; -+ unsigned st_gid; -+ unsigned long long st_rdev; -+ unsigned short int __pad2; -+ long long st_size; -+ long st_blksize; -+ long long st_blocks; -+ long st_atime_; -+ unsigned long st_atime_nsec_; -+ long st_mtime_; -+ unsigned long st_mtime_nsec_; -+ long st_ctime_; -+ unsigned long st_ctime_nsec_; -+ unsigned long __unused4; -+ unsigned long __unused5; -+}; -+#elif defined(__e2k__) -+struct kernel_stat64 { -+ unsigned long long st_dev; -+ unsigned long long st_ino; -+ unsigned int st_mode; -+ unsigned int st_nlink; -+ unsigned int st_uid; -+ unsigned int st_gid; -+ unsigned long long st_rdev; -+ long long st_size; -+ int st_blksize; -+ int __pad2; -+ unsigned long long st_blocks; -+ int st_atime_; -+ unsigned int st_atime_nsec_; -+ int st_mtime_; -+ unsigned int st_mtime_nsec_; -+ int st_ctime_; -+ unsigned int st_ctime_nsec_; -+ unsigned int __unused4; -+ unsigned int __unused5; -+}; -+#else -+struct kernel_stat64 { -+ unsigned long long st_dev; -+ unsigned char __pad0[4]; -+ unsigned __st_ino; -+ unsigned st_mode; -+ unsigned st_nlink; -+ unsigned st_uid; -+ unsigned st_gid; -+ unsigned long long st_rdev; -+ unsigned char __pad3[4]; -+ long long st_size; -+ unsigned st_blksize; -+ unsigned long long st_blocks; -+ unsigned st_atime_; -+ unsigned st_atime_nsec_; -+ unsigned st_mtime_; -+ unsigned st_mtime_nsec_; -+ unsigned st_ctime_; -+ unsigned st_ctime_nsec_; -+ unsigned long long st_ino; -+}; -+#endif -+ -+/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/stat.h */ -+#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) -+typedef unsigned kernel_blkcnt_t; -+typedef unsigned kernel_blksize_t; -+typedef unsigned short kernel_dev_t; -+typedef unsigned short kernel_gid_t; -+typedef unsigned kernel_ino_t; -+typedef unsigned short kernel_mode_t; -+typedef unsigned short kernel_nlink_t; -+typedef unsigned kernel_off_t; -+typedef unsigned kernel_time_t; -+typedef unsigned short kernel_uid_t; -+struct kernel_stat { -+ /* The kernel headers suggest that st_dev and st_rdev should be 32bit -+ * quantities encoding 12bit major and 20bit minor numbers in an interleaved -+ * format. In reality, we do not see useful data in the top bits. So, -+ * we'll leave the padding in here, until we find a better solution. -+ */ -+ kernel_dev_t st_dev; -+ short pad1; -+ kernel_ino_t st_ino; -+ kernel_mode_t st_mode; -+ kernel_nlink_t st_nlink; -+ kernel_uid_t st_uid; -+ kernel_gid_t st_gid; -+ kernel_dev_t st_rdev; -+ short pad2; -+ kernel_off_t st_size; -+ kernel_blksize_t st_blksize; -+ kernel_blkcnt_t st_blocks; -+ kernel_time_t st_atime_; -+ unsigned st_atime_nsec_; -+ kernel_time_t st_mtime_; -+ unsigned st_mtime_nsec_; -+ kernel_time_t st_ctime_; -+ unsigned st_ctime_nsec_; -+ unsigned __unused4; -+ unsigned __unused5; -+}; -+#elif defined(__x86_64__) -+typedef int64_t kernel_blkcnt_t; -+typedef int64_t kernel_blksize_t; -+typedef uint64_t kernel_dev_t; -+typedef unsigned kernel_gid_t; -+typedef uint64_t kernel_ino_t; -+typedef unsigned kernel_mode_t; -+typedef uint64_t kernel_nlink_t; -+typedef int64_t kernel_off_t; -+typedef uint64_t kernel_time_t; -+typedef unsigned kernel_uid_t; -+struct kernel_stat { -+ kernel_dev_t st_dev; -+ kernel_ino_t st_ino; -+ kernel_nlink_t st_nlink; -+ kernel_mode_t st_mode; -+ kernel_uid_t st_uid; -+ kernel_gid_t st_gid; -+ unsigned __pad0; -+ kernel_dev_t st_rdev; -+ kernel_off_t st_size; -+ kernel_blksize_t st_blksize; -+ kernel_blkcnt_t st_blocks; -+ kernel_time_t st_atime_; -+ uint64_t st_atime_nsec_; -+ kernel_time_t st_mtime_; -+ uint64_t st_mtime_nsec_; -+ kernel_time_t st_ctime_; -+ uint64_t st_ctime_nsec_; -+ int64_t __unused4[3]; -+}; -+#elif defined(__PPC__) -+typedef unsigned long kernel_blkcnt_t; -+typedef unsigned long kernel_blksize_t; -+typedef unsigned kernel_dev_t; -+typedef unsigned kernel_gid_t; -+typedef unsigned long kernel_ino_t; -+typedef unsigned long kernel_mode_t; -+typedef unsigned short kernel_nlink_t; -+typedef long kernel_off_t; -+typedef unsigned long kernel_time_t; -+typedef unsigned kernel_uid_t; -+struct kernel_stat { -+ kernel_dev_t st_dev; -+ kernel_ino_t st_ino; -+ kernel_mode_t st_mode; -+ kernel_nlink_t st_nlink; -+ kernel_gid_t st_uid; -+ kernel_uid_t st_gid; -+ kernel_dev_t st_rdev; -+ kernel_off_t st_size; -+ kernel_blksize_t st_blksize; -+ kernel_blkcnt_t st_blocks; -+ kernel_time_t st_atime_; -+ unsigned long st_atime_nsec_; -+ kernel_time_t st_mtime_; -+ unsigned long st_mtime_nsec_; -+ kernel_time_t st_ctime_; -+ unsigned long st_ctime_nsec_; -+ unsigned long __unused4; -+ unsigned long __unused5; -+}; -+#elif (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) -+typedef int kernel_blkcnt_t; -+typedef int kernel_blksize_t; -+typedef unsigned kernel_dev_t; -+typedef unsigned kernel_gid_t; -+typedef unsigned kernel_ino_t; -+typedef unsigned kernel_mode_t; -+typedef unsigned kernel_nlink_t; -+typedef long kernel_off_t; -+typedef long kernel_time_t; -+typedef unsigned kernel_uid_t; -+struct kernel_stat { -+ kernel_dev_t st_dev; -+ int st_pad1[3]; -+ kernel_ino_t st_ino; -+ kernel_mode_t st_mode; -+ kernel_nlink_t st_nlink; -+ kernel_uid_t st_uid; -+ kernel_gid_t st_gid; -+ kernel_dev_t st_rdev; -+ int st_pad2[2]; -+ kernel_off_t st_size; -+ int st_pad3; -+ kernel_time_t st_atime_; -+ long st_atime_nsec_; -+ kernel_time_t st_mtime_; -+ long st_mtime_nsec_; -+ kernel_time_t st_ctime_; -+ long st_ctime_nsec_; -+ kernel_blksize_t st_blksize; -+ kernel_blkcnt_t st_blocks; -+ int st_pad4[14]; -+}; -+#elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64) -+typedef long kernel_blkcnt_t; -+typedef int kernel_blksize_t; -+typedef unsigned long kernel_dev_t; -+typedef unsigned int kernel_gid_t; -+typedef unsigned long kernel_ino_t; -+typedef unsigned int kernel_mode_t; -+typedef unsigned int kernel_nlink_t; -+typedef long kernel_off_t; -+typedef long kernel_time_t; -+typedef unsigned int kernel_uid_t; -+struct kernel_stat { -+ kernel_dev_t st_dev; -+ kernel_ino_t st_ino; -+ kernel_mode_t st_mode; -+ kernel_nlink_t st_nlink; -+ kernel_uid_t st_uid; -+ kernel_gid_t st_gid; -+ kernel_dev_t st_rdev; -+ unsigned long __pad1; -+ kernel_off_t st_size; -+ kernel_blksize_t st_blksize; -+ int __pad2; -+ kernel_blkcnt_t st_blocks; -+ kernel_time_t st_atime_; -+ unsigned long st_atime_nsec_; -+ kernel_time_t st_mtime_; -+ unsigned long st_mtime_nsec_; -+ kernel_time_t st_ctime_; -+ unsigned long st_ctime_nsec_; -+ unsigned int __unused4; -+ unsigned int __unused5; -+}; -+#elif defined(__s390x__) -+typedef long kernel_blkcnt_t; -+typedef unsigned long kernel_blksize_t; -+typedef unsigned long kernel_dev_t; -+typedef unsigned int kernel_gid_t; -+typedef unsigned long kernel_ino_t; -+typedef unsigned int kernel_mode_t; -+typedef unsigned long kernel_nlink_t; -+typedef unsigned long kernel_off_t; -+typedef unsigned long kernel_time_t; -+typedef unsigned int kernel_uid_t; -+struct kernel_stat { -+ kernel_dev_t st_dev; -+ kernel_ino_t st_ino; -+ kernel_nlink_t st_nlink; -+ kernel_mode_t st_mode; -+ kernel_uid_t st_uid; -+ kernel_gid_t st_gid; -+ unsigned int __pad1; -+ kernel_dev_t st_rdev; -+ kernel_off_t st_size; -+ kernel_time_t st_atime_; -+ unsigned long st_atime_nsec_; -+ kernel_time_t st_mtime_; -+ unsigned long st_mtime_nsec_; -+ kernel_time_t st_ctime_; -+ unsigned long st_ctime_nsec_; -+ kernel_blksize_t st_blksize; -+ kernel_blkcnt_t st_blocks; -+ unsigned long __unused[3]; -+}; -+#elif defined(__s390__) -+typedef unsigned long kernel_blkcnt_t; -+typedef unsigned long kernel_blksize_t; -+typedef unsigned short kernel_dev_t; -+typedef unsigned short kernel_gid_t; -+typedef unsigned long kernel_ino_t; -+typedef unsigned short kernel_mode_t; -+typedef unsigned short kernel_nlink_t; -+typedef unsigned long kernel_off_t; -+typedef unsigned long kernel_time_t; -+typedef unsigned short kernel_uid_t; -+struct kernel_stat { -+ kernel_dev_t st_dev; -+ unsigned short __pad1; -+ kernel_ino_t st_ino; -+ kernel_mode_t st_mode; -+ kernel_nlink_t st_nlink; -+ kernel_uid_t st_uid; -+ kernel_gid_t st_gid; -+ kernel_dev_t st_rdev; -+ unsigned short __pad2; -+ kernel_off_t st_size; -+ kernel_blksize_t st_blksize; -+ kernel_blkcnt_t st_blocks; -+ kernel_time_t st_atime_; -+ unsigned long st_atime_nsec_; -+ kernel_time_t st_mtime_; -+ unsigned long st_mtime_nsec_; -+ kernel_time_t st_ctime_; -+ unsigned long st_ctime_nsec_; -+ unsigned long __unused4; -+ unsigned long __unused5; -+}; -+#elif defined(__e2k__) -+typedef unsigned long kernel_blkcnt_t; -+typedef unsigned long kernel_blksize_t; -+typedef unsigned long kernel_dev_t; -+typedef unsigned int kernel_gid_t; -+typedef unsigned long kernel_ino_t; -+typedef unsigned int kernel_mode_t; -+typedef unsigned long kernel_nlink_t; -+typedef unsigned long kernel_off_t; -+typedef unsigned long kernel_time_t; -+typedef unsigned int kernel_uid_t; -+struct kernel_stat { -+ kernel_dev_t st_dev; -+ kernel_ino_t st_ino; -+ kernel_mode_t st_mode; -+ kernel_nlink_t st_nlink; -+ kernel_uid_t st_uid; -+ kernel_gid_t st_gid; -+ kernel_dev_t st_rdev; -+ kernel_off_t st_size; -+ kernel_blksize_t st_blksize; -+ kernel_blkcnt_t st_blocks; -+ kernel_time_t st_atime_; -+ unsigned long st_atime_nsec_; -+ kernel_time_t st_mtime_; -+ unsigned long st_mtime_nsec_; -+ kernel_time_t st_ctime_; -+ unsigned long st_ctime_nsec_; -+}; -+#endif -+ -+/* include/asm-{arm,aarch64,i386,mips,x86_64,ppc,s390}/statfs.h */ -+#ifdef __mips__ -+#if _MIPS_SIM != _MIPS_SIM_ABI64 -+struct kernel_statfs64 { -+ unsigned long f_type; -+ unsigned long f_bsize; -+ unsigned long f_frsize; -+ unsigned long __pad; -+ unsigned long long f_blocks; -+ unsigned long long f_bfree; -+ unsigned long long f_files; -+ unsigned long long f_ffree; -+ unsigned long long f_bavail; -+ struct { int val[2]; } f_fsid; -+ unsigned long f_namelen; -+ unsigned long f_spare[6]; -+}; -+#endif -+#elif defined(__s390__) -+/* See also arch/s390/include/asm/compat.h */ -+struct kernel_statfs64 { -+ unsigned int f_type; -+ unsigned int f_bsize; -+ unsigned long long f_blocks; -+ unsigned long long f_bfree; -+ unsigned long long f_bavail; -+ unsigned long long f_files; -+ unsigned long long f_ffree; -+ struct { int val[2]; } f_fsid; -+ unsigned int f_namelen; -+ unsigned int f_frsize; -+ unsigned int f_flags; -+ unsigned int f_spare[4]; -+}; -+#elif !defined(__x86_64__) -+struct kernel_statfs64 { -+ unsigned long f_type; -+ unsigned long f_bsize; -+ unsigned long long f_blocks; -+ unsigned long long f_bfree; -+ unsigned long long f_bavail; -+ unsigned long long f_files; -+ unsigned long long f_ffree; -+ struct { int val[2]; } f_fsid; -+ unsigned long f_namelen; -+ unsigned long f_frsize; -+ unsigned long f_spare[5]; -+}; -+#endif -+ -+/* include/asm-{arm,i386,mips,x86_64,ppc,generic,s390}/statfs.h */ -+#ifdef __mips__ -+struct kernel_statfs { -+ long f_type; -+ long f_bsize; -+ long f_frsize; -+ long f_blocks; -+ long f_bfree; -+ long f_files; -+ long f_ffree; -+ long f_bavail; -+ struct { int val[2]; } f_fsid; -+ long f_namelen; -+ long f_spare[6]; -+}; -+#elif defined(__x86_64__) -+struct kernel_statfs { -+ /* x86_64 actually defines all these fields as signed, whereas all other */ -+ /* platforms define them as unsigned. Leaving them at unsigned should not */ -+ /* cause any problems. Make sure these are 64-bit even on x32. */ -+ uint64_t f_type; -+ uint64_t f_bsize; -+ uint64_t f_blocks; -+ uint64_t f_bfree; -+ uint64_t f_bavail; -+ uint64_t f_files; -+ uint64_t f_ffree; -+ struct { int val[2]; } f_fsid; -+ uint64_t f_namelen; -+ uint64_t f_frsize; -+ uint64_t f_spare[5]; -+}; -+#elif defined(__s390__) -+struct kernel_statfs { -+ unsigned int f_type; -+ unsigned int f_bsize; -+ unsigned long f_blocks; -+ unsigned long f_bfree; -+ unsigned long f_bavail; -+ unsigned long f_files; -+ unsigned long f_ffree; -+ struct { int val[2]; } f_fsid; -+ unsigned int f_namelen; -+ unsigned int f_frsize; -+ unsigned int f_flags; -+ unsigned int f_spare[4]; -+}; -+#else -+struct kernel_statfs { -+ unsigned long f_type; -+ unsigned long f_bsize; -+ unsigned long f_blocks; -+ unsigned long f_bfree; -+ unsigned long f_bavail; -+ unsigned long f_files; -+ unsigned long f_ffree; -+ struct { int val[2]; } f_fsid; -+ unsigned long f_namelen; -+ unsigned long f_frsize; -+ unsigned long f_spare[5]; -+}; -+#endif -+ -+struct kernel_statx_timestamp { -+ int64_t tv_sec; -+ uint32_t tv_nsec; -+ int32_t __reserved; -+}; -+ -+struct kernel_statx { -+ uint32_t stx_mask; -+ uint32_t stx_blksize; -+ uint64_t stx_attributes; -+ uint32_t stx_nlink; -+ uint32_t stx_uid; -+ uint32_t stx_gid; -+ uint16_t stx_mode; -+ uint16_t __spare0[1]; -+ uint64_t stx_ino; -+ uint64_t stx_size; -+ uint64_t stx_blocks; -+ uint64_t stx_attributes_mask; -+ struct kernel_statx_timestamp stx_atime; -+ struct kernel_statx_timestamp stx_btime; -+ struct kernel_statx_timestamp stx_ctime; -+ struct kernel_statx_timestamp stx_mtime; -+ uint32_t stx_rdev_major; -+ uint32_t stx_rdev_minor; -+ uint32_t stx_dev_major; -+ uint32_t stx_dev_minor; -+ uint64_t stx_mnt_id; -+ uint64_t __spare2; -+ uint64_t __spare3[12]; -+}; -+ -+/* Definitions missing from the standard header files */ -+#ifndef O_DIRECTORY -+#if defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || defined(__aarch64__) -+#define O_DIRECTORY 0040000 -+#else -+#define O_DIRECTORY 0200000 -+#endif -+#endif -+#ifndef NT_PRXFPREG -+#define NT_PRXFPREG 0x46e62b7f -+#endif -+#ifndef PTRACE_GETFPXREGS -+#define PTRACE_GETFPXREGS ((enum __ptrace_request)18) -+#endif -+#ifndef PR_GET_DUMPABLE -+#define PR_GET_DUMPABLE 3 -+#endif -+#ifndef PR_SET_DUMPABLE -+#define PR_SET_DUMPABLE 4 -+#endif -+#ifndef PR_GET_SECCOMP -+#define PR_GET_SECCOMP 21 -+#endif -+#ifndef PR_SET_SECCOMP -+#define PR_SET_SECCOMP 22 -+#endif -+#ifndef AT_FDCWD -+#define AT_FDCWD (-100) -+#endif -+#ifndef AT_SYMLINK_NOFOLLOW -+#define AT_SYMLINK_NOFOLLOW 0x100 -+#endif -+#ifndef AT_REMOVEDIR -+#define AT_REMOVEDIR 0x200 -+#endif -+#ifndef AT_NO_AUTOMOUNT -+#define AT_NO_AUTOMOUNT 0x800 -+#endif -+#ifndef AT_EMPTY_PATH -+#define AT_EMPTY_PATH 0x1000 -+#endif -+#ifndef STATX_BASIC_STATS -+#define STATX_BASIC_STATS 0x000007ffU -+#endif -+#ifndef AT_STATX_SYNC_AS_STAT -+#define AT_STATX_SYNC_AS_STAT 0x0000 -+#endif -+#ifndef MREMAP_FIXED -+#define MREMAP_FIXED 2 -+#endif -+#ifndef SA_RESTORER -+#define SA_RESTORER 0x04000000 -+#endif -+#ifndef CPUCLOCK_PROF -+#define CPUCLOCK_PROF 0 -+#endif -+#ifndef CPUCLOCK_VIRT -+#define CPUCLOCK_VIRT 1 -+#endif -+#ifndef CPUCLOCK_SCHED -+#define CPUCLOCK_SCHED 2 -+#endif -+#ifndef CPUCLOCK_PERTHREAD_MASK -+#define CPUCLOCK_PERTHREAD_MASK 4 -+#endif -+#ifndef MAKE_PROCESS_CPUCLOCK -+#define MAKE_PROCESS_CPUCLOCK(pid, clock) \ -+ ((int)(~(unsigned)(pid) << 3) | (int)(clock)) -+#endif -+#ifndef MAKE_THREAD_CPUCLOCK -+#define MAKE_THREAD_CPUCLOCK(tid, clock) \ -+ ((int)(~(unsigned)(tid) << 3) | \ -+ (int)((clock) | CPUCLOCK_PERTHREAD_MASK)) -+#endif -+ -+#ifndef FUTEX_WAIT -+#define FUTEX_WAIT 0 -+#endif -+#ifndef FUTEX_WAKE -+#define FUTEX_WAKE 1 -+#endif -+#ifndef FUTEX_FD -+#define FUTEX_FD 2 -+#endif -+#ifndef FUTEX_REQUEUE -+#define FUTEX_REQUEUE 3 -+#endif -+#ifndef FUTEX_CMP_REQUEUE -+#define FUTEX_CMP_REQUEUE 4 -+#endif -+#ifndef FUTEX_WAKE_OP -+#define FUTEX_WAKE_OP 5 -+#endif -+#ifndef FUTEX_LOCK_PI -+#define FUTEX_LOCK_PI 6 -+#endif -+#ifndef FUTEX_UNLOCK_PI -+#define FUTEX_UNLOCK_PI 7 -+#endif -+#ifndef FUTEX_TRYLOCK_PI -+#define FUTEX_TRYLOCK_PI 8 -+#endif -+#ifndef FUTEX_PRIVATE_FLAG -+#define FUTEX_PRIVATE_FLAG 128 -+#endif -+#ifndef FUTEX_CMD_MASK -+#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG -+#endif -+#ifndef FUTEX_WAIT_PRIVATE -+#define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) -+#endif -+#ifndef FUTEX_WAKE_PRIVATE -+#define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) -+#endif -+#ifndef FUTEX_REQUEUE_PRIVATE -+#define FUTEX_REQUEUE_PRIVATE (FUTEX_REQUEUE | FUTEX_PRIVATE_FLAG) -+#endif -+#ifndef FUTEX_CMP_REQUEUE_PRIVATE -+#define FUTEX_CMP_REQUEUE_PRIVATE (FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG) -+#endif -+#ifndef FUTEX_WAKE_OP_PRIVATE -+#define FUTEX_WAKE_OP_PRIVATE (FUTEX_WAKE_OP | FUTEX_PRIVATE_FLAG) -+#endif -+#ifndef FUTEX_LOCK_PI_PRIVATE -+#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) -+#endif -+#ifndef FUTEX_UNLOCK_PI_PRIVATE -+#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) -+#endif -+#ifndef FUTEX_TRYLOCK_PI_PRIVATE -+#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) -+#endif -+ -+ -+#if defined(__x86_64__) -+#ifndef ARCH_SET_GS -+#define ARCH_SET_GS 0x1001 -+#endif -+#ifndef ARCH_GET_GS -+#define ARCH_GET_GS 0x1004 -+#endif -+#endif -+ -+#if defined(__i386__) -+#ifndef __NR_quotactl -+#define __NR_quotactl 131 -+#endif -+#ifndef __NR_setresuid -+#define __NR_setresuid 164 -+#define __NR_getresuid 165 -+#define __NR_setresgid 170 -+#define __NR_getresgid 171 -+#endif -+#ifndef __NR_rt_sigaction -+#define __NR_rt_sigreturn 173 -+#define __NR_rt_sigaction 174 -+#define __NR_rt_sigprocmask 175 -+#define __NR_rt_sigpending 176 -+#define __NR_rt_sigsuspend 179 -+#endif -+#ifndef __NR_pread64 -+#define __NR_pread64 180 -+#endif -+#ifndef __NR_pwrite64 -+#define __NR_pwrite64 181 -+#endif -+#ifndef __NR_ugetrlimit -+#define __NR_ugetrlimit 191 -+#endif -+#ifndef __NR_stat64 -+#define __NR_stat64 195 -+#endif -+#ifndef __NR_fstat64 -+#define __NR_fstat64 197 -+#endif -+#ifndef __NR_setresuid32 -+#define __NR_setresuid32 208 -+#define __NR_getresuid32 209 -+#define __NR_setresgid32 210 -+#define __NR_getresgid32 211 -+#endif -+#ifndef __NR_setfsuid32 -+#define __NR_setfsuid32 215 -+#define __NR_setfsgid32 216 -+#endif -+#ifndef __NR_getdents64 -+#define __NR_getdents64 220 -+#endif -+#ifndef __NR_gettid -+#define __NR_gettid 224 -+#endif -+#ifndef __NR_readahead -+#define __NR_readahead 225 -+#endif -+#ifndef __NR_setxattr -+#define __NR_setxattr 226 -+#endif -+#ifndef __NR_lsetxattr -+#define __NR_lsetxattr 227 -+#endif -+#ifndef __NR_getxattr -+#define __NR_getxattr 229 -+#endif -+#ifndef __NR_lgetxattr -+#define __NR_lgetxattr 230 -+#endif -+#ifndef __NR_listxattr -+#define __NR_listxattr 232 -+#endif -+#ifndef __NR_llistxattr -+#define __NR_llistxattr 233 -+#endif -+#ifndef __NR_tkill -+#define __NR_tkill 238 -+#endif -+#ifndef __NR_futex -+#define __NR_futex 240 -+#endif -+#ifndef __NR_sched_setaffinity -+#define __NR_sched_setaffinity 241 -+#define __NR_sched_getaffinity 242 -+#endif -+#ifndef __NR_set_tid_address -+#define __NR_set_tid_address 258 -+#endif -+#ifndef __NR_clock_gettime -+#define __NR_clock_gettime 265 -+#endif -+#ifndef __NR_clock_getres -+#define __NR_clock_getres 266 -+#endif -+#ifndef __NR_statfs64 -+#define __NR_statfs64 268 -+#endif -+#ifndef __NR_fstatfs64 -+#define __NR_fstatfs64 269 -+#endif -+#ifndef __NR_fadvise64_64 -+#define __NR_fadvise64_64 272 -+#endif -+#ifndef __NR_ioprio_set -+#define __NR_ioprio_set 289 -+#endif -+#ifndef __NR_ioprio_get -+#define __NR_ioprio_get 290 -+#endif -+#ifndef __NR_openat -+#define __NR_openat 295 -+#endif -+#ifndef __NR_fstatat64 -+#define __NR_fstatat64 300 -+#endif -+#ifndef __NR_unlinkat -+#define __NR_unlinkat 301 -+#endif -+#ifndef __NR_move_pages -+#define __NR_move_pages 317 -+#endif -+#ifndef __NR_getcpu -+#define __NR_getcpu 318 -+#endif -+#ifndef __NR_fallocate -+#define __NR_fallocate 324 -+#endif -+#ifndef __NR_getrandom -+#define __NR_getrandom 355 -+#endif -+/* End of i386 definitions */ -+#elif defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) -+#ifndef __NR_setresuid -+#define __NR_setresuid (__NR_SYSCALL_BASE + 164) -+#define __NR_getresuid (__NR_SYSCALL_BASE + 165) -+#define __NR_setresgid (__NR_SYSCALL_BASE + 170) -+#define __NR_getresgid (__NR_SYSCALL_BASE + 171) -+#endif -+#ifndef __NR_rt_sigaction -+#define __NR_rt_sigreturn (__NR_SYSCALL_BASE + 173) -+#define __NR_rt_sigaction (__NR_SYSCALL_BASE + 174) -+#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE + 175) -+#define __NR_rt_sigpending (__NR_SYSCALL_BASE + 176) -+#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE + 179) -+#endif -+#ifndef __NR_pread64 -+#define __NR_pread64 (__NR_SYSCALL_BASE + 180) -+#endif -+#ifndef __NR_pwrite64 -+#define __NR_pwrite64 (__NR_SYSCALL_BASE + 181) -+#endif -+#ifndef __NR_ugetrlimit -+#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191) -+#endif -+#ifndef __NR_stat64 -+#define __NR_stat64 (__NR_SYSCALL_BASE + 195) -+#endif -+#ifndef __NR_fstat64 -+#define __NR_fstat64 (__NR_SYSCALL_BASE + 197) -+#endif -+#ifndef __NR_setresuid32 -+#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208) -+#define __NR_getresuid32 (__NR_SYSCALL_BASE + 209) -+#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210) -+#define __NR_getresgid32 (__NR_SYSCALL_BASE + 211) -+#endif -+#ifndef __NR_setfsuid32 -+#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215) -+#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216) -+#endif -+#ifndef __NR_getdents64 -+#define __NR_getdents64 (__NR_SYSCALL_BASE + 217) -+#endif -+#ifndef __NR_gettid -+#define __NR_gettid (__NR_SYSCALL_BASE + 224) -+#endif -+#ifndef __NR_readahead -+#define __NR_readahead (__NR_SYSCALL_BASE + 225) -+#endif -+#ifndef __NR_setxattr -+#define __NR_setxattr (__NR_SYSCALL_BASE + 226) -+#endif -+#ifndef __NR_lsetxattr -+#define __NR_lsetxattr (__NR_SYSCALL_BASE + 227) -+#endif -+#ifndef __NR_getxattr -+#define __NR_getxattr (__NR_SYSCALL_BASE + 229) -+#endif -+#ifndef __NR_lgetxattr -+#define __NR_lgetxattr (__NR_SYSCALL_BASE + 230) -+#endif -+#ifndef __NR_listxattr -+#define __NR_listxattr (__NR_SYSCALL_BASE + 232) -+#endif -+#ifndef __NR_llistxattr -+#define __NR_llistxattr (__NR_SYSCALL_BASE + 233) -+#endif -+#ifndef __NR_tkill -+#define __NR_tkill (__NR_SYSCALL_BASE + 238) -+#endif -+#ifndef __NR_futex -+#define __NR_futex (__NR_SYSCALL_BASE + 240) -+#endif -+#ifndef __NR_sched_setaffinity -+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241) -+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242) -+#endif -+#ifndef __NR_set_tid_address -+#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256) -+#endif -+#ifndef __NR_clock_gettime -+#define __NR_clock_gettime (__NR_SYSCALL_BASE + 263) -+#endif -+#ifndef __NR_clock_getres -+#define __NR_clock_getres (__NR_SYSCALL_BASE + 264) -+#endif -+#ifndef __NR_statfs64 -+#define __NR_statfs64 (__NR_SYSCALL_BASE + 266) -+#endif -+#ifndef __NR_fstatfs64 -+#define __NR_fstatfs64 (__NR_SYSCALL_BASE + 267) -+#endif -+#ifndef __NR_ioprio_set -+#define __NR_ioprio_set (__NR_SYSCALL_BASE + 314) -+#endif -+#ifndef __NR_ioprio_get -+#define __NR_ioprio_get (__NR_SYSCALL_BASE + 315) -+#endif -+#ifndef __NR_fstatat64 -+#define __NR_fstatat64 (__NR_SYSCALL_BASE + 327) -+#endif -+#ifndef __NR_move_pages -+#define __NR_move_pages (__NR_SYSCALL_BASE + 344) -+#endif -+#ifndef __NR_getcpu -+#define __NR_getcpu (__NR_SYSCALL_BASE + 345) -+#endif -+#ifndef __NR_getrandom -+#define __NR_getrandom (__NR_SYSCALL_BASE + 384) -+#endif -+/* End of ARM 3/EABI definitions */ -+#elif defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64) -+#ifndef __NR_setxattr -+#define __NR_setxattr 5 -+#endif -+#ifndef __NR_lsetxattr -+#define __NR_lsetxattr 6 -+#endif -+#ifndef __NR_getxattr -+#define __NR_getxattr 8 -+#endif -+#ifndef __NR_lgetxattr -+#define __NR_lgetxattr 9 -+#endif -+#ifndef __NR_listxattr -+#define __NR_listxattr 11 -+#endif -+#ifndef __NR_llistxattr -+#define __NR_llistxattr 12 -+#endif -+#ifndef __NR_ioprio_set -+#define __NR_ioprio_set 30 -+#endif -+#ifndef __NR_ioprio_get -+#define __NR_ioprio_get 31 -+#endif -+#ifndef __NR_unlinkat -+#define __NR_unlinkat 35 -+#endif -+#ifndef __NR_fallocate -+#define __NR_fallocate 47 -+#endif -+#ifndef __NR_openat -+#define __NR_openat 56 -+#endif -+#ifndef __NR_quotactl -+#define __NR_quotactl 60 -+#endif -+#ifndef __NR_getdents64 -+#define __NR_getdents64 61 -+#endif -+#ifndef __NR_getdents -+// when getdents is not available, getdents64 is used for both. -+#define __NR_getdents __NR_getdents64 -+#endif -+#ifndef __NR_pread64 -+#define __NR_pread64 67 -+#endif -+#ifndef __NR_pwrite64 -+#define __NR_pwrite64 68 -+#endif -+#ifndef __NR_ppoll -+#define __NR_ppoll 73 -+#endif -+#ifndef __NR_readlinkat -+#define __NR_readlinkat 78 -+#endif -+#if !defined(__loongarch_lp64) -+#ifndef __NR_newfstatat -+#define __NR_newfstatat 79 -+#endif -+#endif -+#ifndef __NR_set_tid_address -+#define __NR_set_tid_address 96 -+#endif -+#ifndef __NR_futex -+#define __NR_futex 98 -+#endif -+#ifndef __NR_clock_gettime -+#define __NR_clock_gettime 113 -+#endif -+#ifndef __NR_clock_getres -+#define __NR_clock_getres 114 -+#endif -+#ifndef __NR_sched_setaffinity -+#define __NR_sched_setaffinity 122 -+#define __NR_sched_getaffinity 123 -+#endif -+#ifndef __NR_tkill -+#define __NR_tkill 130 -+#endif -+#ifndef __NR_setresuid -+#define __NR_setresuid 147 -+#define __NR_getresuid 148 -+#define __NR_setresgid 149 -+#define __NR_getresgid 150 -+#endif -+#ifndef __NR_gettid -+#define __NR_gettid 178 -+#endif -+#ifndef __NR_readahead -+#define __NR_readahead 213 -+#endif -+#ifndef __NR_fadvise64 -+#define __NR_fadvise64 223 -+#endif -+#ifndef __NR_move_pages -+#define __NR_move_pages 239 -+#endif -+#ifndef __NR_getrandom -+#define __NR_getrandom 278 -+#endif -+#ifndef __NR_statx -+#define __NR_statx 291 -+#endif -+#elif defined(__x86_64__) -+#ifndef __NR_pread64 -+#define __NR_pread64 17 -+#endif -+#ifndef __NR_pwrite64 -+#define __NR_pwrite64 18 -+#endif -+#ifndef __NR_setresuid -+#define __NR_setresuid 117 -+#define __NR_getresuid 118 -+#define __NR_setresgid 119 -+#define __NR_getresgid 120 -+#endif -+#ifndef __NR_quotactl -+#define __NR_quotactl 179 -+#endif -+#ifndef __NR_gettid -+#define __NR_gettid 186 -+#endif -+#ifndef __NR_readahead -+#define __NR_readahead 187 -+#endif -+#ifndef __NR_setxattr -+#define __NR_setxattr 188 -+#endif -+#ifndef __NR_lsetxattr -+#define __NR_lsetxattr 189 -+#endif -+#ifndef __NR_getxattr -+#define __NR_getxattr 191 -+#endif -+#ifndef __NR_lgetxattr -+#define __NR_lgetxattr 192 -+#endif -+#ifndef __NR_listxattr -+#define __NR_listxattr 194 -+#endif -+#ifndef __NR_llistxattr -+#define __NR_llistxattr 195 -+#endif -+#ifndef __NR_tkill -+#define __NR_tkill 200 -+#endif -+#ifndef __NR_futex -+#define __NR_futex 202 -+#endif -+#ifndef __NR_sched_setaffinity -+#define __NR_sched_setaffinity 203 -+#define __NR_sched_getaffinity 204 -+#endif -+#ifndef __NR_getdents64 -+#define __NR_getdents64 217 -+#endif -+#ifndef __NR_getdents -+// when getdents is not available, getdents64 is used for both. -+#define __NR_getdents __NR_getdents64 -+#endif -+#ifndef __NR_set_tid_address -+#define __NR_set_tid_address 218 -+#endif -+#ifndef __NR_fadvise64 -+#define __NR_fadvise64 221 -+#endif -+#ifndef __NR_clock_gettime -+#define __NR_clock_gettime 228 -+#endif -+#ifndef __NR_clock_getres -+#define __NR_clock_getres 229 -+#endif -+#ifndef __NR_ioprio_set -+#define __NR_ioprio_set 251 -+#endif -+#ifndef __NR_ioprio_get -+#define __NR_ioprio_get 252 -+#endif -+#ifndef __NR_openat -+#define __NR_openat 257 -+#endif -+#ifndef __NR_newfstatat -+#define __NR_newfstatat 262 -+#endif -+#ifndef __NR_unlinkat -+#define __NR_unlinkat 263 -+#endif -+#ifndef __NR_move_pages -+#define __NR_move_pages 279 -+#endif -+#ifndef __NR_fallocate -+#define __NR_fallocate 285 -+#endif -+#ifndef __NR_getrandom -+#define __NR_getrandom 318 -+#endif -+/* End of x86-64 definitions */ -+#elif defined(__mips__) -+#if _MIPS_SIM == _MIPS_SIM_ABI32 -+#ifndef __NR_setresuid -+#define __NR_setresuid (__NR_Linux + 185) -+#define __NR_getresuid (__NR_Linux + 186) -+#define __NR_setresgid (__NR_Linux + 190) -+#define __NR_getresgid (__NR_Linux + 191) -+#endif -+#ifndef __NR_rt_sigaction -+#define __NR_rt_sigreturn (__NR_Linux + 193) -+#define __NR_rt_sigaction (__NR_Linux + 194) -+#define __NR_rt_sigprocmask (__NR_Linux + 195) -+#define __NR_rt_sigpending (__NR_Linux + 196) -+#define __NR_rt_sigsuspend (__NR_Linux + 199) -+#endif -+#ifndef __NR_pread64 -+#define __NR_pread64 (__NR_Linux + 200) -+#endif -+#ifndef __NR_pwrite64 -+#define __NR_pwrite64 (__NR_Linux + 201) -+#endif -+#ifndef __NR_stat64 -+#define __NR_stat64 (__NR_Linux + 213) -+#endif -+#ifndef __NR_fstat64 -+#define __NR_fstat64 (__NR_Linux + 215) -+#endif -+#ifndef __NR_getdents64 -+#define __NR_getdents64 (__NR_Linux + 219) -+#endif -+#ifndef __NR_gettid -+#define __NR_gettid (__NR_Linux + 222) -+#endif -+#ifndef __NR_readahead -+#define __NR_readahead (__NR_Linux + 223) -+#endif -+#ifndef __NR_setxattr -+#define __NR_setxattr (__NR_Linux + 224) -+#endif -+#ifndef __NR_lsetxattr -+#define __NR_lsetxattr (__NR_Linux + 225) -+#endif -+#ifndef __NR_getxattr -+#define __NR_getxattr (__NR_Linux + 227) -+#endif -+#ifndef __NR_lgetxattr -+#define __NR_lgetxattr (__NR_Linux + 228) -+#endif -+#ifndef __NR_listxattr -+#define __NR_listxattr (__NR_Linux + 230) -+#endif -+#ifndef __NR_llistxattr -+#define __NR_llistxattr (__NR_Linux + 231) -+#endif -+#ifndef __NR_tkill -+#define __NR_tkill (__NR_Linux + 236) -+#endif -+#ifndef __NR_futex -+#define __NR_futex (__NR_Linux + 238) -+#endif -+#ifndef __NR_sched_setaffinity -+#define __NR_sched_setaffinity (__NR_Linux + 239) -+#define __NR_sched_getaffinity (__NR_Linux + 240) -+#endif -+#ifndef __NR_set_tid_address -+#define __NR_set_tid_address (__NR_Linux + 252) -+#endif -+#ifndef __NR_statfs64 -+#define __NR_statfs64 (__NR_Linux + 255) -+#endif -+#ifndef __NR_fstatfs64 -+#define __NR_fstatfs64 (__NR_Linux + 256) -+#endif -+#ifndef __NR_clock_gettime -+#define __NR_clock_gettime (__NR_Linux + 263) -+#endif -+#ifndef __NR_clock_getres -+#define __NR_clock_getres (__NR_Linux + 264) -+#endif -+#ifndef __NR_openat -+#define __NR_openat (__NR_Linux + 288) -+#endif -+#ifndef __NR_fstatat -+#define __NR_fstatat (__NR_Linux + 293) -+#endif -+#ifndef __NR_unlinkat -+#define __NR_unlinkat (__NR_Linux + 294) -+#endif -+#ifndef __NR_move_pages -+#define __NR_move_pages (__NR_Linux + 308) -+#endif -+#ifndef __NR_getcpu -+#define __NR_getcpu (__NR_Linux + 312) -+#endif -+#ifndef __NR_ioprio_set -+#define __NR_ioprio_set (__NR_Linux + 314) -+#endif -+#ifndef __NR_ioprio_get -+#define __NR_ioprio_get (__NR_Linux + 315) -+#endif -+#ifndef __NR_getrandom -+#define __NR_getrandom (__NR_Linux + 353) -+#endif -+/* End of MIPS (old 32bit API) definitions */ -+#elif _MIPS_SIM == _MIPS_SIM_ABI64 -+#ifndef __NR_pread64 -+#define __NR_pread64 (__NR_Linux + 16) -+#endif -+#ifndef __NR_pwrite64 -+#define __NR_pwrite64 (__NR_Linux + 17) -+#endif -+#ifndef __NR_setresuid -+#define __NR_setresuid (__NR_Linux + 115) -+#define __NR_getresuid (__NR_Linux + 116) -+#define __NR_setresgid (__NR_Linux + 117) -+#define __NR_getresgid (__NR_Linux + 118) -+#endif -+#ifndef __NR_gettid -+#define __NR_gettid (__NR_Linux + 178) -+#endif -+#ifndef __NR_readahead -+#define __NR_readahead (__NR_Linux + 179) -+#endif -+#ifndef __NR_setxattr -+#define __NR_setxattr (__NR_Linux + 180) -+#endif -+#ifndef __NR_lsetxattr -+#define __NR_lsetxattr (__NR_Linux + 181) -+#endif -+#ifndef __NR_getxattr -+#define __NR_getxattr (__NR_Linux + 183) -+#endif -+#ifndef __NR_lgetxattr -+#define __NR_lgetxattr (__NR_Linux + 184) -+#endif -+#ifndef __NR_listxattr -+#define __NR_listxattr (__NR_Linux + 186) -+#endif -+#ifndef __NR_llistxattr -+#define __NR_llistxattr (__NR_Linux + 187) -+#endif -+#ifndef __NR_tkill -+#define __NR_tkill (__NR_Linux + 192) -+#endif -+#ifndef __NR_futex -+#define __NR_futex (__NR_Linux + 194) -+#endif -+#ifndef __NR_sched_setaffinity -+#define __NR_sched_setaffinity (__NR_Linux + 195) -+#define __NR_sched_getaffinity (__NR_Linux + 196) -+#endif -+#ifndef __NR_set_tid_address -+#define __NR_set_tid_address (__NR_Linux + 212) -+#endif -+#ifndef __NR_clock_gettime -+#define __NR_clock_gettime (__NR_Linux + 222) -+#endif -+#ifndef __NR_clock_getres -+#define __NR_clock_getres (__NR_Linux + 223) -+#endif -+#ifndef __NR_openat -+#define __NR_openat (__NR_Linux + 247) -+#endif -+#ifndef __NR_fstatat -+#define __NR_fstatat (__NR_Linux + 252) -+#endif -+#ifndef __NR_unlinkat -+#define __NR_unlinkat (__NR_Linux + 253) -+#endif -+#ifndef __NR_move_pages -+#define __NR_move_pages (__NR_Linux + 267) -+#endif -+#ifndef __NR_getcpu -+#define __NR_getcpu (__NR_Linux + 271) -+#endif -+#ifndef __NR_ioprio_set -+#define __NR_ioprio_set (__NR_Linux + 273) -+#endif -+#ifndef __NR_ioprio_get -+#define __NR_ioprio_get (__NR_Linux + 274) -+#endif -+#ifndef __NR_getrandom -+#define __NR_getrandom (__NR_Linux + 313) -+#endif -+/* End of MIPS (64bit API) definitions */ -+#else -+#ifndef __NR_setresuid -+#define __NR_setresuid (__NR_Linux + 115) -+#define __NR_getresuid (__NR_Linux + 116) -+#define __NR_setresgid (__NR_Linux + 117) -+#define __NR_getresgid (__NR_Linux + 118) -+#endif -+#ifndef __NR_gettid -+#define __NR_gettid (__NR_Linux + 178) -+#endif -+#ifndef __NR_readahead -+#define __NR_readahead (__NR_Linux + 179) -+#endif -+#ifndef __NR_setxattr -+#define __NR_setxattr (__NR_Linux + 180) -+#endif -+#ifndef __NR_lsetxattr -+#define __NR_lsetxattr (__NR_Linux + 181) -+#endif -+#ifndef __NR_getxattr -+#define __NR_getxattr (__NR_Linux + 183) -+#endif -+#ifndef __NR_lgetxattr -+#define __NR_lgetxattr (__NR_Linux + 184) -+#endif -+#ifndef __NR_listxattr -+#define __NR_listxattr (__NR_Linux + 186) -+#endif -+#ifndef __NR_llistxattr -+#define __NR_llistxattr (__NR_Linux + 187) -+#endif -+#ifndef __NR_tkill -+#define __NR_tkill (__NR_Linux + 192) -+#endif -+#ifndef __NR_futex -+#define __NR_futex (__NR_Linux + 194) -+#endif -+#ifndef __NR_sched_setaffinity -+#define __NR_sched_setaffinity (__NR_Linux + 195) -+#define __NR_sched_getaffinity (__NR_Linux + 196) -+#endif -+#ifndef __NR_set_tid_address -+#define __NR_set_tid_address (__NR_Linux + 213) -+#endif -+#ifndef __NR_statfs64 -+#define __NR_statfs64 (__NR_Linux + 217) -+#endif -+#ifndef __NR_fstatfs64 -+#define __NR_fstatfs64 (__NR_Linux + 218) -+#endif -+#ifndef __NR_clock_gettime -+#define __NR_clock_gettime (__NR_Linux + 226) -+#endif -+#ifndef __NR_clock_getres -+#define __NR_clock_getres (__NR_Linux + 227) -+#endif -+#ifndef __NR_openat -+#define __NR_openat (__NR_Linux + 251) -+#endif -+#ifndef __NR_fstatat -+#define __NR_fstatat (__NR_Linux + 256) -+#endif -+#ifndef __NR_unlinkat -+#define __NR_unlinkat (__NR_Linux + 257) -+#endif -+#ifndef __NR_move_pages -+#define __NR_move_pages (__NR_Linux + 271) -+#endif -+#ifndef __NR_getcpu -+#define __NR_getcpu (__NR_Linux + 275) -+#endif -+#ifndef __NR_ioprio_set -+#define __NR_ioprio_set (__NR_Linux + 277) -+#endif -+#ifndef __NR_ioprio_get -+#define __NR_ioprio_get (__NR_Linux + 278) -+#endif -+/* End of MIPS (new 32bit API) definitions */ -+#endif -+/* End of MIPS definitions */ -+#elif defined(__PPC__) -+#ifndef __NR_setfsuid -+#define __NR_setfsuid 138 -+#define __NR_setfsgid 139 -+#endif -+#ifndef __NR_setresuid -+#define __NR_setresuid 164 -+#define __NR_getresuid 165 -+#define __NR_setresgid 169 -+#define __NR_getresgid 170 -+#endif -+#ifndef __NR_rt_sigaction -+#define __NR_rt_sigreturn 172 -+#define __NR_rt_sigaction 173 -+#define __NR_rt_sigprocmask 174 -+#define __NR_rt_sigpending 175 -+#define __NR_rt_sigsuspend 178 -+#endif -+#ifndef __NR_pread64 -+#define __NR_pread64 179 -+#endif -+#ifndef __NR_pwrite64 -+#define __NR_pwrite64 180 -+#endif -+#ifndef __NR_ugetrlimit -+#define __NR_ugetrlimit 190 -+#endif -+#ifndef __NR_readahead -+#define __NR_readahead 191 -+#endif -+#ifndef __NR_stat64 -+#define __NR_stat64 195 -+#endif -+#ifndef __NR_fstat64 -+#define __NR_fstat64 197 -+#endif -+#ifndef __NR_getdents64 -+#define __NR_getdents64 202 -+#endif -+#ifndef __NR_gettid -+#define __NR_gettid 207 -+#endif -+#ifndef __NR_tkill -+#define __NR_tkill 208 -+#endif -+#ifndef __NR_setxattr -+#define __NR_setxattr 209 -+#endif -+#ifndef __NR_lsetxattr -+#define __NR_lsetxattr 210 -+#endif -+#ifndef __NR_getxattr -+#define __NR_getxattr 212 -+#endif -+#ifndef __NR_lgetxattr -+#define __NR_lgetxattr 213 -+#endif -+#ifndef __NR_listxattr -+#define __NR_listxattr 215 -+#endif -+#ifndef __NR_llistxattr -+#define __NR_llistxattr 216 -+#endif -+#ifndef __NR_futex -+#define __NR_futex 221 -+#endif -+#ifndef __NR_sched_setaffinity -+#define __NR_sched_setaffinity 222 -+#define __NR_sched_getaffinity 223 -+#endif -+#ifndef __NR_set_tid_address -+#define __NR_set_tid_address 232 -+#endif -+#ifndef __NR_clock_gettime -+#define __NR_clock_gettime 246 -+#endif -+#ifndef __NR_clock_getres -+#define __NR_clock_getres 247 -+#endif -+#ifndef __NR_statfs64 -+#define __NR_statfs64 252 -+#endif -+#ifndef __NR_fstatfs64 -+#define __NR_fstatfs64 253 -+#endif -+#ifndef __NR_fadvise64_64 -+#define __NR_fadvise64_64 254 -+#endif -+#ifndef __NR_ioprio_set -+#define __NR_ioprio_set 273 -+#endif -+#ifndef __NR_ioprio_get -+#define __NR_ioprio_get 274 -+#endif -+#ifndef __NR_openat -+#define __NR_openat 286 -+#endif -+#ifndef __NR_fstatat64 -+#define __NR_fstatat64 291 -+#endif -+#ifndef __NR_unlinkat -+#define __NR_unlinkat 292 -+#endif -+#ifndef __NR_move_pages -+#define __NR_move_pages 301 -+#endif -+#ifndef __NR_getcpu -+#define __NR_getcpu 302 -+#endif -+/* End of powerpc definitions */ -+#elif defined(__s390__) -+#ifndef __NR_quotactl -+#define __NR_quotactl 131 -+#endif -+#ifndef __NR_rt_sigreturn -+#define __NR_rt_sigreturn 173 -+#endif -+#ifndef __NR_rt_sigaction -+#define __NR_rt_sigaction 174 -+#endif -+#ifndef __NR_rt_sigprocmask -+#define __NR_rt_sigprocmask 175 -+#endif -+#ifndef __NR_rt_sigpending -+#define __NR_rt_sigpending 176 -+#endif -+#ifndef __NR_rt_sigsuspend -+#define __NR_rt_sigsuspend 179 -+#endif -+#ifndef __NR_pread64 -+#define __NR_pread64 180 -+#endif -+#ifndef __NR_pwrite64 -+#define __NR_pwrite64 181 -+#endif -+#ifndef __NR_getdents64 -+#define __NR_getdents64 220 -+#endif -+#ifndef __NR_readahead -+#define __NR_readahead 222 -+#endif -+#ifndef __NR_setxattr -+#define __NR_setxattr 224 -+#endif -+#ifndef __NR_lsetxattr -+#define __NR_lsetxattr 225 -+#endif -+#ifndef __NR_getxattr -+#define __NR_getxattr 227 -+#endif -+#ifndef __NR_lgetxattr -+#define __NR_lgetxattr 228 -+#endif -+#ifndef __NR_listxattr -+#define __NR_listxattr 230 -+#endif -+#ifndef __NR_llistxattr -+#define __NR_llistxattr 231 -+#endif -+#ifndef __NR_gettid -+#define __NR_gettid 236 -+#endif -+#ifndef __NR_tkill -+#define __NR_tkill 237 -+#endif -+#ifndef __NR_futex -+#define __NR_futex 238 -+#endif -+#ifndef __NR_sched_setaffinity -+#define __NR_sched_setaffinity 239 -+#endif -+#ifndef __NR_sched_getaffinity -+#define __NR_sched_getaffinity 240 -+#endif -+#ifndef __NR_set_tid_address -+#define __NR_set_tid_address 252 -+#endif -+#ifndef __NR_clock_gettime -+#define __NR_clock_gettime 260 -+#endif -+#ifndef __NR_clock_getres -+#define __NR_clock_getres 261 -+#endif -+#ifndef __NR_statfs64 -+#define __NR_statfs64 265 -+#endif -+#ifndef __NR_fstatfs64 -+#define __NR_fstatfs64 266 -+#endif -+#ifndef __NR_ioprio_set -+#define __NR_ioprio_set 282 -+#endif -+#ifndef __NR_ioprio_get -+#define __NR_ioprio_get 283 -+#endif -+#ifndef __NR_openat -+#define __NR_openat 288 -+#endif -+#ifndef __NR_unlinkat -+#define __NR_unlinkat 294 -+#endif -+#ifndef __NR_move_pages -+#define __NR_move_pages 310 -+#endif -+#ifndef __NR_getcpu -+#define __NR_getcpu 311 -+#endif -+#ifndef __NR_fallocate -+#define __NR_fallocate 314 -+#endif -+/* Some syscalls are named/numbered differently between s390 and s390x. */ -+#ifdef __s390x__ -+# ifndef __NR_getrlimit -+# define __NR_getrlimit 191 -+# endif -+# ifndef __NR_setresuid -+# define __NR_setresuid 208 -+# endif -+# ifndef __NR_getresuid -+# define __NR_getresuid 209 -+# endif -+# ifndef __NR_setresgid -+# define __NR_setresgid 210 -+# endif -+# ifndef __NR_getresgid -+# define __NR_getresgid 211 -+# endif -+# ifndef __NR_setfsuid -+# define __NR_setfsuid 215 -+# endif -+# ifndef __NR_setfsgid -+# define __NR_setfsgid 216 -+# endif -+# ifndef __NR_fadvise64 -+# define __NR_fadvise64 253 -+# endif -+# ifndef __NR_newfstatat -+# define __NR_newfstatat 293 -+# endif -+#else /* __s390x__ */ -+# ifndef __NR_getrlimit -+# define __NR_getrlimit 76 -+# endif -+# ifndef __NR_setfsuid -+# define __NR_setfsuid 138 -+# endif -+# ifndef __NR_setfsgid -+# define __NR_setfsgid 139 -+# endif -+# ifndef __NR_setresuid -+# define __NR_setresuid 164 -+# endif -+# ifndef __NR_getresuid -+# define __NR_getresuid 165 -+# endif -+# ifndef __NR_setresgid -+# define __NR_setresgid 170 -+# endif -+# ifndef __NR_getresgid -+# define __NR_getresgid 171 -+# endif -+# ifndef __NR_ugetrlimit -+# define __NR_ugetrlimit 191 -+# endif -+# ifndef __NR_mmap2 -+# define __NR_mmap2 192 -+# endif -+# ifndef __NR_setresuid32 -+# define __NR_setresuid32 208 -+# endif -+# ifndef __NR_getresuid32 -+# define __NR_getresuid32 209 -+# endif -+# ifndef __NR_setresgid32 -+# define __NR_setresgid32 210 -+# endif -+# ifndef __NR_getresgid32 -+# define __NR_getresgid32 211 -+# endif -+# ifndef __NR_setfsuid32 -+# define __NR_setfsuid32 215 -+# endif -+# ifndef __NR_setfsgid32 -+# define __NR_setfsgid32 216 -+# endif -+# ifndef __NR_fadvise64_64 -+# define __NR_fadvise64_64 264 -+# endif -+# ifndef __NR_fstatat64 -+# define __NR_fstatat64 293 -+# endif -+#endif /* __s390__ */ -+/* End of s390/s390x definitions */ -+#endif -+ -+ -+/* After forking, we must make sure to only call system calls. */ -+#if defined(__BOUNDED_POINTERS__) -+ #error "Need to port invocations of syscalls for bounded ptrs" -+#else -+ /* The core dumper and the thread lister get executed after threads -+ * have been suspended. As a consequence, we cannot call any functions -+ * that acquire locks. Unfortunately, libc wraps most system calls -+ * (e.g. in order to implement pthread_atfork, and to make calls -+ * cancellable), which means we cannot call these functions. Instead, -+ * we have to call syscall() directly. -+ */ -+ #undef LSS_ERRNO -+ #ifdef SYS_ERRNO -+ /* Allow the including file to override the location of errno. This can -+ * be useful when using clone() with the CLONE_VM option. -+ */ -+ #define LSS_ERRNO SYS_ERRNO -+ #else -+ #define LSS_ERRNO errno -+ #endif -+ -+ #undef LSS_INLINE -+ #ifdef SYS_INLINE -+ #define LSS_INLINE SYS_INLINE -+ #else -+ #define LSS_INLINE static inline -+ #endif -+ -+ /* Allow the including file to override the prefix used for all new -+ * system calls. By default, it will be set to "sys_". -+ */ -+ #undef LSS_NAME -+ #ifndef SYS_PREFIX -+ #define LSS_NAME(name) sys_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX < 0 -+ #define LSS_NAME(name) name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 0 -+ #define LSS_NAME(name) sys0_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 1 -+ #define LSS_NAME(name) sys1_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 2 -+ #define LSS_NAME(name) sys2_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 3 -+ #define LSS_NAME(name) sys3_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 4 -+ #define LSS_NAME(name) sys4_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 5 -+ #define LSS_NAME(name) sys5_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 6 -+ #define LSS_NAME(name) sys6_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 7 -+ #define LSS_NAME(name) sys7_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 8 -+ #define LSS_NAME(name) sys8_##name -+ #elif defined(SYS_PREFIX) && SYS_PREFIX == 9 -+ #define LSS_NAME(name) sys9_##name -+ #endif -+ -+ #undef LSS_RETURN -+ #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) \ -+ || defined(__ARM_EABI__) || defined(__aarch64__) || defined(__s390__) \ -+ || defined(__e2k__) || defined(__riscv) || defined(__loongarch_lp64) -+ /* Failing system calls return a negative result in the range of -+ * -1..-4095. These are "errno" values with the sign inverted. -+ */ -+ #define LSS_RETURN(type, res) \ -+ do { \ -+ if ((unsigned long)(res) >= (unsigned long)(-4095)) { \ -+ LSS_ERRNO = (int)(-(res)); \ -+ res = -1; \ -+ } \ -+ return (type) (res); \ -+ } while (0) -+ #elif defined(__mips__) -+ /* On MIPS, failing system calls return -1, and set errno in a -+ * separate CPU register. -+ */ -+ #define LSS_RETURN(type, res, err) \ -+ do { \ -+ if (err) { \ -+ unsigned long __errnovalue = (res); \ -+ LSS_ERRNO = __errnovalue; \ -+ res = -1; \ -+ } \ -+ return (type) (res); \ -+ } while (0) -+ #elif defined(__PPC__) -+ /* On PPC, failing system calls return -1, and set errno in a -+ * separate CPU register. See linux/unistd.h. -+ */ -+ #define LSS_RETURN(type, res, err) \ -+ do { \ -+ if (err & 0x10000000 ) { \ -+ LSS_ERRNO = (res); \ -+ res = -1; \ -+ } \ -+ return (type) (res); \ -+ } while (0) -+ #endif -+ #if defined(__i386__) -+ /* In PIC mode (e.g. when building shared libraries), gcc for i386 -+ * reserves ebx. Unfortunately, most distribution ship with implementations -+ * of _syscallX() which clobber ebx. -+ * Also, most definitions of _syscallX() neglect to mark "memory" as being -+ * clobbered. This causes problems with compilers, that do a better job -+ * at optimizing across __asm__ calls. -+ * So, we just have to redefine all of the _syscallX() macros. -+ */ -+ #undef LSS_ENTRYPOINT -+ #ifdef SYS_SYSCALL_ENTRYPOINT -+ static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { -+ void (**entrypoint)(void); -+ asm volatile(".bss\n" -+ ".align 8\n" -+ ".globl " SYS_SYSCALL_ENTRYPOINT "\n" -+ ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" -+ ".previous\n" -+ /* This logically does 'lea "SYS_SYSCALL_ENTRYPOINT", %0' */ -+ "call 0f\n" -+ "0:pop %0\n" -+ "add $_GLOBAL_OFFSET_TABLE_+[.-0b], %0\n" -+ "mov " SYS_SYSCALL_ENTRYPOINT "@GOT(%0), %0\n" -+ : "=r"(entrypoint)); -+ return entrypoint; -+ } -+ -+ #define LSS_ENTRYPOINT ".bss\n" \ -+ ".align 8\n" \ -+ ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \ -+ ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \ -+ ".previous\n" \ -+ /* Check the SYS_SYSCALL_ENTRYPOINT vector */ \ -+ "push %%eax\n" \ -+ "call 10000f\n" \ -+ "10000:pop %%eax\n" \ -+ "add $_GLOBAL_OFFSET_TABLE_+[.-10000b], %%eax\n" \ -+ "mov " SYS_SYSCALL_ENTRYPOINT \ -+ "@GOT(%%eax), %%eax\n" \ -+ "mov 0(%%eax), %%eax\n" \ -+ "test %%eax, %%eax\n" \ -+ "jz 10002f\n" \ -+ "push %%eax\n" \ -+ "call 10001f\n" \ -+ "10001:pop %%eax\n" \ -+ "add $(10003f-10001b), %%eax\n" \ -+ "xchg 4(%%esp), %%eax\n" \ -+ "ret\n" \ -+ "10002:pop %%eax\n" \ -+ "int $0x80\n" \ -+ "10003:\n" -+ #else -+ #define LSS_ENTRYPOINT "int $0x80\n" -+ #endif -+ #undef LSS_BODY -+ #define LSS_BODY(type,args...) \ -+ long __res; \ -+ __asm__ __volatile__("push %%ebx\n" \ -+ "movl %2,%%ebx\n" \ -+ LSS_ENTRYPOINT \ -+ "pop %%ebx" \ -+ args \ -+ : "memory"); \ -+ LSS_RETURN(type,__res) -+ #undef _syscall0 -+ #define _syscall0(type,name) \ -+ type LSS_NAME(name)(void) { \ -+ long __res; \ -+ __asm__ volatile(LSS_ENTRYPOINT \ -+ : "=a" (__res) \ -+ : "0" (__NR_##name) \ -+ : "memory"); \ -+ LSS_RETURN(type,__res); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type,name,type1,arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_BODY(type, \ -+ : "=a" (__res) \ -+ : "0" (__NR_##name), "ri" ((long)(arg1))); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type,name,type1,arg1,type2,arg2) \ -+ type LSS_NAME(name)(type1 arg1,type2 arg2) { \ -+ LSS_BODY(type, \ -+ : "=a" (__res) \ -+ : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \ -+ } -+ #undef _syscall3 -+ #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -+ type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \ -+ LSS_BODY(type, \ -+ : "=a" (__res) \ -+ : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ -+ "d" ((long)(arg3))); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_BODY(type, \ -+ : "=a" (__res) \ -+ : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \ -+ "d" ((long)(arg3)),"S" ((long)(arg4))); \ -+ } -+ #undef _syscall5 -+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ long __res; \ -+ __asm__ __volatile__("push %%ebx\n" \ -+ "movl %2,%%ebx\n" \ -+ "movl %1,%%eax\n" \ -+ LSS_ENTRYPOINT \ -+ "pop %%ebx" \ -+ : "=a" (__res) \ -+ : "i" (__NR_##name), "ri" ((long)(arg1)), \ -+ "c" ((long)(arg2)), "d" ((long)(arg3)), \ -+ "S" ((long)(arg4)), "D" ((long)(arg5)) \ -+ : "memory"); \ -+ LSS_RETURN(type,__res); \ -+ } -+ #undef _syscall6 -+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ long __res; \ -+ struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \ -+ __asm__ __volatile__("push %%ebp\n" \ -+ "push %%ebx\n" \ -+ "movl 4(%2),%%ebp\n" \ -+ "movl 0(%2), %%ebx\n" \ -+ "movl %1,%%eax\n" \ -+ LSS_ENTRYPOINT \ -+ "pop %%ebx\n" \ -+ "pop %%ebp" \ -+ : "=a" (__res) \ -+ : "i" (__NR_##name), "0" ((long)(&__s)), \ -+ "c" ((long)(arg2)), "d" ((long)(arg3)), \ -+ "S" ((long)(arg4)), "D" ((long)(arg5)) \ -+ : "memory"); \ -+ LSS_RETURN(type,__res); \ -+ } -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ long __res; -+ __asm__ __volatile__(/* if (fn == NULL) -+ * return -EINVAL; -+ */ -+ "movl %3,%%ecx\n" -+ "jecxz 1f\n" -+ -+ /* if (child_stack == NULL) -+ * return -EINVAL; -+ */ -+ "movl %4,%%ecx\n" -+ "jecxz 1f\n" -+ -+ /* Set up alignment of the child stack: -+ * child_stack = (child_stack & ~0xF) - 20; -+ */ -+ "andl $-16,%%ecx\n" -+ "subl $20,%%ecx\n" -+ -+ /* Push "arg" and "fn" onto the stack that will be -+ * used by the child. -+ */ -+ "movl %6,%%eax\n" -+ "movl %%eax,4(%%ecx)\n" -+ "movl %3,%%eax\n" -+ "movl %%eax,(%%ecx)\n" -+ -+ /* %eax = syscall(%eax = __NR_clone, -+ * %ebx = flags, -+ * %ecx = child_stack, -+ * %edx = parent_tidptr, -+ * %esi = newtls, -+ * %edi = child_tidptr) -+ * Also, make sure that %ebx gets preserved as it is -+ * used in PIC mode. -+ */ -+ "movl %8,%%esi\n" -+ "movl %7,%%edx\n" -+ "movl %5,%%eax\n" -+ "movl %9,%%edi\n" -+ "pushl %%ebx\n" -+ "movl %%eax,%%ebx\n" -+ "movl %2,%%eax\n" -+ LSS_ENTRYPOINT -+ -+ /* In the parent: restore %ebx -+ * In the child: move "fn" into %ebx -+ */ -+ "popl %%ebx\n" -+ -+ /* if (%eax != 0) -+ * return %eax; -+ */ -+ "test %%eax,%%eax\n" -+ "jnz 1f\n" -+ -+ /* In the child, now. Terminate frame pointer chain. -+ */ -+ "movl $0,%%ebp\n" -+ -+ /* Call "fn". "arg" is already on the stack. -+ */ -+ "call *%%ebx\n" -+ -+ /* Call _exit(%ebx). Unfortunately older versions -+ * of gcc restrict the number of arguments that can -+ * be passed to asm(). So, we need to hard-code the -+ * system call number. -+ */ -+ "movl %%eax,%%ebx\n" -+ "movl $1,%%eax\n" -+ LSS_ENTRYPOINT -+ -+ /* Return to parent. -+ */ -+ "1:\n" -+ : "=a" (__res) -+ : "0"(-EINVAL), "i"(__NR_clone), -+ "m"(fn), "m"(child_stack), "m"(flags), "m"(arg), -+ "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr) -+ : "memory", "ecx", "edx", "esi", "edi"); -+ LSS_RETURN(int, __res); -+ } -+ -+ LSS_INLINE _syscall1(int, set_thread_area, void *, u) -+ LSS_INLINE _syscall1(int, get_thread_area, void *, u) -+ -+ LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { -+ /* On i386, the kernel does not know how to return from a signal -+ * handler. Instead, it relies on user space to provide a -+ * restorer function that calls the {rt_,}sigreturn() system call. -+ * Unfortunately, we cannot just reference the glibc version of this -+ * function, as glibc goes out of its way to make it inaccessible. -+ */ -+ void (*res)(void); -+ __asm__ __volatile__("call 2f\n" -+ "0:.align 16\n" -+ "1:movl %1,%%eax\n" -+ LSS_ENTRYPOINT -+ "2:popl %0\n" -+ "addl $(1b-0b),%0\n" -+ : "=a" (res) -+ : "i" (__NR_rt_sigreturn)); -+ return res; -+ } -+ LSS_INLINE void (*LSS_NAME(restore)(void))(void) { -+ /* On i386, the kernel does not know how to return from a signal -+ * handler. Instead, it relies on user space to provide a -+ * restorer function that calls the {rt_,}sigreturn() system call. -+ * Unfortunately, we cannot just reference the glibc version of this -+ * function, as glibc goes out of its way to make it inaccessible. -+ */ -+ void (*res)(void); -+ __asm__ __volatile__("call 2f\n" -+ "0:.align 16\n" -+ "1:pop %%eax\n" -+ "movl %1,%%eax\n" -+ LSS_ENTRYPOINT -+ "2:popl %0\n" -+ "addl $(1b-0b),%0\n" -+ : "=a" (res) -+ : "i" (__NR_sigreturn)); -+ return res; -+ } -+ #elif defined(__x86_64__) -+ /* There are no known problems with any of the _syscallX() macros -+ * currently shipping for x86_64, but we still need to be able to define -+ * our own version so that we can override the location of the errno -+ * location (e.g. when using the clone() system call with the CLONE_VM -+ * option). -+ */ -+ #undef LSS_ENTRYPOINT -+ #ifdef SYS_SYSCALL_ENTRYPOINT -+ static inline void (**LSS_NAME(get_syscall_entrypoint)(void))(void) { -+ void (**entrypoint)(void); -+ asm volatile(".bss\n" -+ ".align 8\n" -+ ".globl " SYS_SYSCALL_ENTRYPOINT "\n" -+ ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" -+ ".previous\n" -+ "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %0\n" -+ : "=r"(entrypoint)); -+ return entrypoint; -+ } -+ -+ #define LSS_ENTRYPOINT \ -+ ".bss\n" \ -+ ".align 8\n" \ -+ ".globl " SYS_SYSCALL_ENTRYPOINT "\n" \ -+ ".common " SYS_SYSCALL_ENTRYPOINT ",8,8\n" \ -+ ".previous\n" \ -+ "mov " SYS_SYSCALL_ENTRYPOINT "@GOTPCREL(%%rip), %%rcx\n" \ -+ "mov 0(%%rcx), %%rcx\n" \ -+ "test %%rcx, %%rcx\n" \ -+ "jz 10001f\n" \ -+ "call *%%rcx\n" \ -+ "jmp 10002f\n" \ -+ "10001:syscall\n" \ -+ "10002:\n" -+ -+ #else -+ #define LSS_ENTRYPOINT "syscall\n" -+ #endif -+ -+ /* The x32 ABI has 32 bit longs, but the syscall interface is 64 bit. -+ * We need to explicitly cast to an unsigned 64 bit type to avoid implicit -+ * sign extension. We can't cast pointers directly because those are -+ * 32 bits, and gcc will dump ugly warnings about casting from a pointer -+ * to an integer of a different size. -+ */ -+ #undef LSS_SYSCALL_ARG -+ #define LSS_SYSCALL_ARG(a) ((uint64_t)(uintptr_t)(a)) -+ #undef _LSS_RETURN -+ #define _LSS_RETURN(type, res, cast) \ -+ do { \ -+ if ((uint64_t)(res) >= (uint64_t)(-4095)) { \ -+ LSS_ERRNO = (int)(-(res)); \ -+ res = -1; \ -+ } \ -+ return (type)(cast)(res); \ -+ } while (0) -+ #undef LSS_RETURN -+ #define LSS_RETURN(type, res) _LSS_RETURN(type, res, uintptr_t) -+ -+ #undef _LSS_BODY -+ #define _LSS_BODY(nr, type, name, cast, ...) \ -+ long long __res; \ -+ __asm__ __volatile__(LSS_BODY_ASM##nr LSS_ENTRYPOINT \ -+ : "=a" (__res) \ -+ : "0" (__NR_##name) LSS_BODY_ARG##nr(__VA_ARGS__) \ -+ : LSS_BODY_CLOBBER##nr "r11", "rcx", "memory"); \ -+ _LSS_RETURN(type, __res, cast) -+ #undef LSS_BODY -+ #define LSS_BODY(nr, type, name, args...) \ -+ _LSS_BODY(nr, type, name, uintptr_t, ## args) -+ -+ #undef LSS_BODY_ASM0 -+ #undef LSS_BODY_ASM1 -+ #undef LSS_BODY_ASM2 -+ #undef LSS_BODY_ASM3 -+ #undef LSS_BODY_ASM4 -+ #undef LSS_BODY_ASM5 -+ #undef LSS_BODY_ASM6 -+ #define LSS_BODY_ASM0 -+ #define LSS_BODY_ASM1 LSS_BODY_ASM0 -+ #define LSS_BODY_ASM2 LSS_BODY_ASM1 -+ #define LSS_BODY_ASM3 LSS_BODY_ASM2 -+ #define LSS_BODY_ASM4 LSS_BODY_ASM3 "movq %5,%%r10;" -+ #define LSS_BODY_ASM5 LSS_BODY_ASM4 "movq %6,%%r8;" -+ #define LSS_BODY_ASM6 LSS_BODY_ASM5 "movq %7,%%r9;" -+ -+ #undef LSS_BODY_CLOBBER0 -+ #undef LSS_BODY_CLOBBER1 -+ #undef LSS_BODY_CLOBBER2 -+ #undef LSS_BODY_CLOBBER3 -+ #undef LSS_BODY_CLOBBER4 -+ #undef LSS_BODY_CLOBBER5 -+ #undef LSS_BODY_CLOBBER6 -+ #define LSS_BODY_CLOBBER0 -+ #define LSS_BODY_CLOBBER1 LSS_BODY_CLOBBER0 -+ #define LSS_BODY_CLOBBER2 LSS_BODY_CLOBBER1 -+ #define LSS_BODY_CLOBBER3 LSS_BODY_CLOBBER2 -+ #define LSS_BODY_CLOBBER4 LSS_BODY_CLOBBER3 "r10", -+ #define LSS_BODY_CLOBBER5 LSS_BODY_CLOBBER4 "r8", -+ #define LSS_BODY_CLOBBER6 LSS_BODY_CLOBBER5 "r9", -+ -+ #undef LSS_BODY_ARG0 -+ #undef LSS_BODY_ARG1 -+ #undef LSS_BODY_ARG2 -+ #undef LSS_BODY_ARG3 -+ #undef LSS_BODY_ARG4 -+ #undef LSS_BODY_ARG5 -+ #undef LSS_BODY_ARG6 -+ #define LSS_BODY_ARG0() -+ #define LSS_BODY_ARG1(arg1) \ -+ LSS_BODY_ARG0(), "D" (arg1) -+ #define LSS_BODY_ARG2(arg1, arg2) \ -+ LSS_BODY_ARG1(arg1), "S" (arg2) -+ #define LSS_BODY_ARG3(arg1, arg2, arg3) \ -+ LSS_BODY_ARG2(arg1, arg2), "d" (arg3) -+ #define LSS_BODY_ARG4(arg1, arg2, arg3, arg4) \ -+ LSS_BODY_ARG3(arg1, arg2, arg3), "r" (arg4) -+ #define LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5) \ -+ LSS_BODY_ARG4(arg1, arg2, arg3, arg4), "r" (arg5) -+ #define LSS_BODY_ARG6(arg1, arg2, arg3, arg4, arg5, arg6) \ -+ LSS_BODY_ARG5(arg1, arg2, arg3, arg4, arg5), "r" (arg6) -+ -+ #undef _syscall0 -+ #define _syscall0(type,name) \ -+ type LSS_NAME(name)(void) { \ -+ LSS_BODY(0, type, name); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type,name,type1,arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_BODY(1, type, name, LSS_SYSCALL_ARG(arg1)); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type,name,type1,arg1,type2,arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ LSS_BODY(2, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2));\ -+ } -+ #undef _syscall3 -+ #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ LSS_BODY(3, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ -+ LSS_SYSCALL_ARG(arg3)); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_BODY(4, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ -+ LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4));\ -+ } -+ #undef _syscall5 -+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_BODY(5, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ -+ LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ -+ LSS_SYSCALL_ARG(arg5)); \ -+ } -+ #undef _syscall6 -+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ LSS_BODY(6, type, name, LSS_SYSCALL_ARG(arg1), LSS_SYSCALL_ARG(arg2), \ -+ LSS_SYSCALL_ARG(arg3), LSS_SYSCALL_ARG(arg4), \ -+ LSS_SYSCALL_ARG(arg5), LSS_SYSCALL_ARG(arg6));\ -+ } -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ long long __res; -+ { -+ __asm__ __volatile__(/* if (fn == NULL) -+ * return -EINVAL; -+ */ -+ "testq %4,%4\n" -+ "jz 1f\n" -+ -+ /* if (child_stack == NULL) -+ * return -EINVAL; -+ */ -+ "testq %5,%5\n" -+ "jz 1f\n" -+ -+ /* childstack -= 2*sizeof(void *); -+ */ -+ "subq $16,%5\n" -+ -+ /* Push "arg" and "fn" onto the stack that will be -+ * used by the child. -+ */ -+ "movq %7,8(%5)\n" -+ "movq %4,0(%5)\n" -+ -+ /* %rax = syscall(%rax = __NR_clone, -+ * %rdi = flags, -+ * %rsi = child_stack, -+ * %rdx = parent_tidptr, -+ * %r8 = new_tls, -+ * %r10 = child_tidptr) -+ */ -+ "movq %2,%%rax\n" -+ "movq %9,%%r8\n" -+ "movq %10,%%r10\n" -+ LSS_ENTRYPOINT -+ -+ /* if (%rax != 0) -+ * return; -+ */ -+ "testq %%rax,%%rax\n" -+ "jnz 1f\n" -+ -+ /* In the child. Terminate frame pointer chain. -+ */ -+ "xorq %%rbp,%%rbp\n" -+ -+ /* Call "fn(arg)". -+ */ -+ "popq %%rax\n" -+ "popq %%rdi\n" -+ "call *%%rax\n" -+ -+ /* Call _exit(%ebx). -+ */ -+ "movq %%rax,%%rdi\n" -+ "movq %3,%%rax\n" -+ LSS_ENTRYPOINT -+ -+ /* Return to parent. -+ */ -+ "1:\n" -+ : "=a" (__res) -+ : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit), -+ "r"(LSS_SYSCALL_ARG(fn)), -+ "S"(LSS_SYSCALL_ARG(child_stack)), -+ "D"(LSS_SYSCALL_ARG(flags)), -+ "r"(LSS_SYSCALL_ARG(arg)), -+ "d"(LSS_SYSCALL_ARG(parent_tidptr)), -+ "r"(LSS_SYSCALL_ARG(newtls)), -+ "r"(LSS_SYSCALL_ARG(child_tidptr)) -+ : "memory", "r8", "r10", "r11", "rcx"); -+ } -+ LSS_RETURN(int, __res); -+ } -+ LSS_INLINE _syscall2(int, arch_prctl, int, c, void *, a) -+ -+ LSS_INLINE void (*LSS_NAME(restore_rt)(void))(void) { -+ /* On x86-64, the kernel does not know how to return from -+ * a signal handler. Instead, it relies on user space to provide a -+ * restorer function that calls the rt_sigreturn() system call. -+ * Unfortunately, we cannot just reference the glibc version of this -+ * function, as glibc goes out of its way to make it inaccessible. -+ */ -+ long long res; -+ __asm__ __volatile__("jmp 2f\n" -+ ".align 16\n" -+ "1:movq %1,%%rax\n" -+ LSS_ENTRYPOINT -+ "2:leaq 1b(%%rip),%0\n" -+ : "=r" (res) -+ : "i" (__NR_rt_sigreturn)); -+ return (void (*)(void))(uintptr_t)res; -+ } -+ #elif defined(__ARM_ARCH_3__) -+ /* Most definitions of _syscallX() neglect to mark "memory" as being -+ * clobbered. This causes problems with compilers, that do a better job -+ * at optimizing across __asm__ calls. -+ * So, we just have to redefine all of the _syscallX() macros. -+ */ -+ #undef LSS_REG -+ #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a -+ #undef LSS_BODY -+ #define LSS_BODY(type,name,args...) \ -+ register long __res_r0 __asm__("r0"); \ -+ long __res; \ -+ __asm__ __volatile__ (__syscall(name) \ -+ : "=r"(__res_r0) : args : "lr", "memory"); \ -+ __res = __res_r0; \ -+ LSS_RETURN(type, __res) -+ #undef _syscall0 -+ #define _syscall0(type, name) \ -+ type LSS_NAME(name)(void) { \ -+ LSS_BODY(type, name); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type, name, type1, arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type, name, type1, arg1, type2, arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ -+ } -+ #undef _syscall3 -+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ -+ } -+ #undef _syscall5 -+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4)); \ -+ } -+ #undef _syscall6 -+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4), "r"(__r5)); \ -+ } -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ long __res; -+ { -+ register int __flags __asm__("r0") = flags; -+ register void *__stack __asm__("r1") = child_stack; -+ register void *__ptid __asm__("r2") = parent_tidptr; -+ register void *__tls __asm__("r3") = newtls; -+ register int *__ctid __asm__("r4") = child_tidptr; -+ __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL) -+ * return -EINVAL; -+ */ -+ "cmp %2,#0\n" -+ "cmpne %3,#0\n" -+ "moveq %0,%1\n" -+ "beq 1f\n" -+ -+ /* Push "arg" and "fn" onto the stack that will be -+ * used by the child. -+ */ -+ "str %5,[%3,#-4]!\n" -+ "str %2,[%3,#-4]!\n" -+ -+ /* %r0 = syscall(%r0 = flags, -+ * %r1 = child_stack, -+ * %r2 = parent_tidptr, -+ * %r3 = newtls, -+ * %r4 = child_tidptr) -+ */ -+ __syscall(clone)"\n" -+ -+ /* if (%r0 != 0) -+ * return %r0; -+ */ -+ "movs %0,r0\n" -+ "bne 1f\n" -+ -+ /* In the child, now. Call "fn(arg)". -+ */ -+ "ldr r0,[sp, #4]\n" -+ "mov lr,pc\n" -+ "ldr pc,[sp]\n" -+ -+ /* Call _exit(%r0). -+ */ -+ __syscall(exit)"\n" -+ "1:\n" -+ : "=r" (__res) -+ : "i"(-EINVAL), -+ "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), -+ "r"(__ptid), "r"(__tls), "r"(__ctid) -+ : "cc", "lr", "memory"); -+ } -+ LSS_RETURN(int, __res); -+ } -+ #elif defined(__ARM_EABI__) -+ /* Most definitions of _syscallX() neglect to mark "memory" as being -+ * clobbered. This causes problems with compilers, that do a better job -+ * at optimizing across __asm__ calls. -+ * So, we just have to redefine all fo the _syscallX() macros. -+ */ -+ #undef LSS_REG -+ #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a -+ #undef LSS_BODY -+ #define LSS_BODY(type,name,args...) \ -+ register long __res_r0 __asm__("r0"); \ -+ long __res; \ -+ __asm__ __volatile__ ("push {r7}\n" \ -+ "mov r7, %1\n" \ -+ "swi 0x0\n" \ -+ "pop {r7}\n" \ -+ : "=r"(__res_r0) \ -+ : "i"(__NR_##name) , ## args \ -+ : "lr", "memory"); \ -+ __res = __res_r0; \ -+ LSS_RETURN(type, __res) -+ #undef _syscall0 -+ #define _syscall0(type, name) \ -+ type LSS_NAME(name)(void) { \ -+ LSS_BODY(type, name); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type, name, type1, arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type, name, type1, arg1, type2, arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ -+ } -+ #undef _syscall3 -+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ -+ } -+ #undef _syscall5 -+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4)); \ -+ } -+ #undef _syscall6 -+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4), "r"(__r5)); \ -+ } -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ long __res; -+ if (fn == NULL || child_stack == NULL) { -+ __res = -EINVAL; -+ LSS_RETURN(int, __res); -+ } -+ -+ /* Push "arg" and "fn" onto the stack that will be -+ * used by the child. -+ */ -+ { -+ uintptr_t* cstack = (uintptr_t*)child_stack - 2; -+ cstack[0] = (uintptr_t)fn; -+ cstack[1] = (uintptr_t)arg; -+ child_stack = cstack; -+ } -+ { -+ register int __flags __asm__("r0") = flags; -+ register void *__stack __asm__("r1") = child_stack; -+ register void *__ptid __asm__("r2") = parent_tidptr; -+ register void *__tls __asm__("r3") = newtls; -+ register int *__ctid __asm__("r4") = child_tidptr; -+ __asm__ __volatile__( -+#ifdef __thumb2__ -+ "push {r7}\n" -+#endif -+ /* %r0 = syscall(%r0 = flags, -+ * %r1 = child_stack, -+ * %r2 = parent_tidptr, -+ * %r3 = newtls, -+ * %r4 = child_tidptr) -+ */ -+ "mov r7, %6\n" -+ "swi 0x0\n" -+ -+ /* if (%r0 != 0) -+ * return %r0; -+ */ -+ "cmp r0, #0\n" -+ "bne 1f\n" -+ -+ /* In the child, now. Call "fn(arg)". -+ */ -+ "ldr r0,[sp, #4]\n" -+ -+ "ldr lr,[sp]\n" -+ "blx lr\n" -+ -+ /* Call _exit(%r0). -+ */ -+ "mov r7, %7\n" -+ "swi 0x0\n" -+ /* Unreachable */ -+ "bkpt #0\n" -+ "1:\n" -+#ifdef __thumb2__ -+ "pop {r7}\n" -+#endif -+ "movs %0,r0\n" -+ : "=r"(__res) -+ : "r"(__stack), "r"(__flags), "r"(__ptid), "r"(__tls), "r"(__ctid), -+ "i"(__NR_clone), "i"(__NR_exit) -+ : "cc", "lr", "memory" -+#ifndef __thumb2__ -+ , "r7" -+#endif -+ ); -+ } -+ LSS_RETURN(int, __res); -+ } -+ #elif defined(__aarch64__) -+ /* Most definitions of _syscallX() neglect to mark "memory" as being -+ * clobbered. This causes problems with compilers, that do a better job -+ * at optimizing across __asm__ calls. -+ * So, we just have to redefine all of the _syscallX() macros. -+ */ -+ #undef LSS_REG -+ #define LSS_REG(r,a) register int64_t __r##r __asm__("x"#r) = (int64_t)a -+ #undef LSS_BODY -+ #define LSS_BODY(type,name,args...) \ -+ register int64_t __res_x0 __asm__("x0"); \ -+ int64_t __res; \ -+ __asm__ __volatile__ ("mov x8, %1\n" \ -+ "svc 0x0\n" \ -+ : "=r"(__res_x0) \ -+ : "i"(__NR_##name) , ## args \ -+ : "x8", "memory"); \ -+ __res = __res_x0; \ -+ LSS_RETURN(type, __res) -+ #undef _syscall0 -+ #define _syscall0(type, name) \ -+ type LSS_NAME(name)(void) { \ -+ LSS_BODY(type, name); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type, name, type1, arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type, name, type1, arg1, type2, arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ -+ } -+ #undef _syscall3 -+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ -+ } -+ #undef _syscall5 -+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4)); \ -+ } -+ #undef _syscall6 -+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4), "r"(__r5)); \ -+ } -+ -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ int64_t __res; -+ { -+ register uint64_t __flags __asm__("x0") = (uint64_t)flags; -+ register void *__stack __asm__("x1") = child_stack; -+ register void *__ptid __asm__("x2") = parent_tidptr; -+ register void *__tls __asm__("x3") = newtls; -+ register int *__ctid __asm__("x4") = child_tidptr; -+ __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be -+ * used by the child. -+ */ -+ "stp %1, %4, [%2, #-16]!\n" -+ -+ /* %x0 = syscall(%x0 = flags, -+ * %x1 = child_stack, -+ * %x2 = parent_tidptr, -+ * %x3 = newtls, -+ * %x4 = child_tidptr) -+ */ -+ "mov x8, %8\n" -+ "svc 0x0\n" -+ -+ /* if (%r0 != 0) -+ * return %r0; -+ */ -+ "mov %0, x0\n" -+ "cbnz x0, 1f\n" -+ -+ /* In the child, now. Call "fn(arg)". -+ */ -+ "ldp x1, x0, [sp], #16\n" -+ "blr x1\n" -+ -+ /* Call _exit(%r0). -+ */ -+ "mov x8, %9\n" -+ "svc 0x0\n" -+ "1:\n" -+ : "=r" (__res) -+ : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), -+ "r"(__ptid), "r"(__tls), "r"(__ctid), -+ "i"(__NR_clone), "i"(__NR_exit) -+ : "cc", "x8", "memory"); -+ } -+ LSS_RETURN(int, __res); -+ } -+ #elif defined(__mips__) -+ #undef LSS_REG -+ #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \ -+ (unsigned long)(a) -+ #undef LSS_BODY -+ #undef LSS_SYSCALL_CLOBBERS -+ #if _MIPS_SIM == _MIPS_SIM_ABI32 -+ #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", \ -+ "$11", "$12", "$13", "$14", "$15", \ -+ "$24", "$25", "hi", "lo", "memory" -+ #else -+ #define LSS_SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", \ -+ "$13", "$14", "$15", "$24", "$25", \ -+ "hi", "lo", "memory" -+ #endif -+ #define LSS_BODY(type,name,r7,...) \ -+ register unsigned long __v0 __asm__("$2") = __NR_##name; \ -+ __asm__ __volatile__ ("syscall\n" \ -+ : "=r"(__v0), r7 (__r7) \ -+ : "0"(__v0), ##__VA_ARGS__ \ -+ : LSS_SYSCALL_CLOBBERS); \ -+ LSS_RETURN(type, __v0, __r7) -+ #undef _syscall0 -+ #define _syscall0(type, name) \ -+ type LSS_NAME(name)(void) { \ -+ register unsigned long __r7 __asm__("$7"); \ -+ LSS_BODY(type, name, "=r"); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type, name, type1, arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ register unsigned long __r7 __asm__("$7"); \ -+ LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type, name, type1, arg1, type2, arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ register unsigned long __r7 __asm__("$7"); \ -+ LSS_REG(4, arg1); LSS_REG(5, arg2); \ -+ LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \ -+ } -+ #undef _syscall3 -+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ register unsigned long __r7 __asm__("$7"); \ -+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ -+ LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ -+ LSS_REG(7, arg4); \ -+ LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \ -+ } -+ #undef _syscall5 -+ #if _MIPS_SIM == _MIPS_SIM_ABI32 -+ /* The old 32bit MIPS system call API passes the fifth and sixth argument -+ * on the stack, whereas the new APIs use registers "r8" and "r9". -+ */ -+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ -+ LSS_REG(7, arg4); \ -+ register unsigned long __v0 __asm__("$2") = __NR_##name; \ -+ __asm__ __volatile__ (".set noreorder\n" \ -+ "subu $29, 32\n" \ -+ "sw %5, 16($29)\n" \ -+ "syscall\n" \ -+ "addiu $29, 32\n" \ -+ ".set reorder\n" \ -+ : "+r"(__v0), "+r" (__r7) \ -+ : "r"(__r4), "r"(__r5), \ -+ "r"(__r6), "r" ((unsigned long)arg5) \ -+ : "$8", "$9", "$10", "$11", "$12", \ -+ "$13", "$14", "$15", "$24", "$25", \ -+ "memory"); \ -+ LSS_RETURN(type, __v0, __r7); \ -+ } -+ #else -+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ -+ LSS_REG(7, arg4); LSS_REG(8, arg5); \ -+ LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ -+ "r"(__r8)); \ -+ } -+ #endif -+ #undef _syscall6 -+ #if _MIPS_SIM == _MIPS_SIM_ABI32 -+ /* The old 32bit MIPS system call API passes the fifth and sixth argument -+ * on the stack, whereas the new APIs use registers "r8" and "r9". -+ */ -+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ -+ LSS_REG(7, arg4); \ -+ register unsigned long __v0 __asm__("$2") = __NR_##name; \ -+ __asm__ __volatile__ (".set noreorder\n" \ -+ "subu $29, 32\n" \ -+ "sw %5, 16($29)\n" \ -+ "sw %6, 20($29)\n" \ -+ "syscall\n" \ -+ "addiu $29, 32\n" \ -+ ".set reorder\n" \ -+ : "+r"(__v0), "+r" (__r7) \ -+ : "r"(__r4), "r"(__r5), \ -+ "r"(__r6), "r" ((unsigned long)arg5), \ -+ "r" ((unsigned long)arg6) \ -+ : "$8", "$9", "$10", "$11", "$12", \ -+ "$13", "$14", "$15", "$24", "$25", \ -+ "memory"); \ -+ LSS_RETURN(type, __v0, __r7); \ -+ } -+ #else -+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5,type6 arg6) { \ -+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \ -+ LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \ -+ LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \ -+ "r"(__r8), "r"(__r9)); \ -+ } -+ #endif -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ register unsigned long __v0 __asm__("$2") = -EINVAL; -+ register unsigned long __r7 __asm__("$7") = (unsigned long)newtls; -+ { -+ register int __flags __asm__("$4") = flags; -+ register void *__stack __asm__("$5") = child_stack; -+ register void *__ptid __asm__("$6") = parent_tidptr; -+ register int *__ctid __asm__("$8") = child_tidptr; -+ __asm__ __volatile__( -+ #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 -+ "subu $29,24\n" -+ #elif _MIPS_SIM == _MIPS_SIM_NABI32 -+ "sub $29,16\n" -+ #else -+ "dsubu $29,16\n" -+ #endif -+ -+ /* if (fn == NULL || child_stack == NULL) -+ * return -EINVAL; -+ */ -+ "beqz %4,1f\n" -+ "beqz %5,1f\n" -+ -+ /* Push "arg" and "fn" onto the stack that will be -+ * used by the child. -+ */ -+ #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 -+ "subu %5,32\n" -+ "sw %4,0(%5)\n" -+ "sw %7,4(%5)\n" -+ #elif _MIPS_SIM == _MIPS_SIM_NABI32 -+ "sub %5,32\n" -+ "sw %4,0(%5)\n" -+ "sw %7,8(%5)\n" -+ #else -+ "dsubu %5,32\n" -+ "sd %4,0(%5)\n" -+ "sd %7,8(%5)\n" -+ #endif -+ -+ /* $7 = syscall($4 = flags, -+ * $5 = child_stack, -+ * $6 = parent_tidptr, -+ * $7 = newtls, -+ * $8 = child_tidptr) -+ */ -+ "li $2,%2\n" -+ "syscall\n" -+ -+ /* if ($7 != 0) -+ * return $2; -+ */ -+ "bnez $7,1f\n" -+ "bnez $2,1f\n" -+ -+ /* In the child, now. Call "fn(arg)". -+ */ -+ #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 -+ "lw $25,0($29)\n" -+ "lw $4,4($29)\n" -+ #elif _MIPS_SIM == _MIPS_SIM_NABI32 -+ "lw $25,0($29)\n" -+ "lw $4,8($29)\n" -+ #else -+ "ld $25,0($29)\n" -+ "ld $4,8($29)\n" -+ #endif -+ "jalr $25\n" -+ -+ /* Call _exit($2) -+ */ -+ "move $4,$2\n" -+ "li $2,%3\n" -+ "syscall\n" -+ -+ "1:\n" -+ #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32 -+ "addu $29, 24\n" -+ #elif _MIPS_SIM == _MIPS_SIM_NABI32 -+ "add $29, 16\n" -+ #else -+ "daddu $29,16\n" -+ #endif -+ : "+r" (__v0), "+r" (__r7) -+ : "i"(__NR_clone), "i"(__NR_exit), "r"(fn), -+ "r"(__stack), "r"(__flags), "r"(arg), -+ "r"(__ptid), "r"(__ctid) -+ : "$9", "$10", "$11", "$12", "$13", "$14", "$15", -+ "$24", "$25", "memory"); -+ } -+ LSS_RETURN(int, __v0, __r7); -+ } -+ #elif defined (__PPC__) -+ #undef LSS_LOADARGS_0 -+ #define LSS_LOADARGS_0(name, dummy...) \ -+ __sc_0 = __NR_##name -+ #undef LSS_LOADARGS_1 -+ #define LSS_LOADARGS_1(name, arg1) \ -+ LSS_LOADARGS_0(name); \ -+ __sc_3 = (unsigned long) (arg1) -+ #undef LSS_LOADARGS_2 -+ #define LSS_LOADARGS_2(name, arg1, arg2) \ -+ LSS_LOADARGS_1(name, arg1); \ -+ __sc_4 = (unsigned long) (arg2) -+ #undef LSS_LOADARGS_3 -+ #define LSS_LOADARGS_3(name, arg1, arg2, arg3) \ -+ LSS_LOADARGS_2(name, arg1, arg2); \ -+ __sc_5 = (unsigned long) (arg3) -+ #undef LSS_LOADARGS_4 -+ #define LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4) \ -+ LSS_LOADARGS_3(name, arg1, arg2, arg3); \ -+ __sc_6 = (unsigned long) (arg4) -+ #undef LSS_LOADARGS_5 -+ #define LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5) \ -+ LSS_LOADARGS_4(name, arg1, arg2, arg3, arg4); \ -+ __sc_7 = (unsigned long) (arg5) -+ #undef LSS_LOADARGS_6 -+ #define LSS_LOADARGS_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ -+ LSS_LOADARGS_5(name, arg1, arg2, arg3, arg4, arg5); \ -+ __sc_8 = (unsigned long) (arg6) -+ #undef LSS_ASMINPUT_0 -+ #define LSS_ASMINPUT_0 "0" (__sc_0) -+ #undef LSS_ASMINPUT_1 -+ #define LSS_ASMINPUT_1 LSS_ASMINPUT_0, "1" (__sc_3) -+ #undef LSS_ASMINPUT_2 -+ #define LSS_ASMINPUT_2 LSS_ASMINPUT_1, "2" (__sc_4) -+ #undef LSS_ASMINPUT_3 -+ #define LSS_ASMINPUT_3 LSS_ASMINPUT_2, "3" (__sc_5) -+ #undef LSS_ASMINPUT_4 -+ #define LSS_ASMINPUT_4 LSS_ASMINPUT_3, "4" (__sc_6) -+ #undef LSS_ASMINPUT_5 -+ #define LSS_ASMINPUT_5 LSS_ASMINPUT_4, "5" (__sc_7) -+ #undef LSS_ASMINPUT_6 -+ #define LSS_ASMINPUT_6 LSS_ASMINPUT_5, "6" (__sc_8) -+ #undef LSS_BODY -+ #define LSS_BODY(nr, type, name, args...) \ -+ long __sc_ret, __sc_err; \ -+ { \ -+ register unsigned long __sc_0 __asm__ ("r0"); \ -+ register unsigned long __sc_3 __asm__ ("r3"); \ -+ register unsigned long __sc_4 __asm__ ("r4"); \ -+ register unsigned long __sc_5 __asm__ ("r5"); \ -+ register unsigned long __sc_6 __asm__ ("r6"); \ -+ register unsigned long __sc_7 __asm__ ("r7"); \ -+ register unsigned long __sc_8 __asm__ ("r8"); \ -+ \ -+ LSS_LOADARGS_##nr(name, args); \ -+ __asm__ __volatile__ \ -+ ("sc\n\t" \ -+ "mfcr %0" \ -+ : "=&r" (__sc_0), \ -+ "=&r" (__sc_3), "=&r" (__sc_4), \ -+ "=&r" (__sc_5), "=&r" (__sc_6), \ -+ "=&r" (__sc_7), "=&r" (__sc_8) \ -+ : LSS_ASMINPUT_##nr \ -+ : "cr0", "ctr", "memory", \ -+ "r9", "r10", "r11", "r12"); \ -+ __sc_ret = __sc_3; \ -+ __sc_err = __sc_0; \ -+ } \ -+ LSS_RETURN(type, __sc_ret, __sc_err) -+ #undef _syscall0 -+ #define _syscall0(type, name) \ -+ type LSS_NAME(name)(void) { \ -+ LSS_BODY(0, type, name); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type, name, type1, arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_BODY(1, type, name, arg1); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type, name, type1, arg1, type2, arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ LSS_BODY(2, type, name, arg1, arg2); \ -+ } -+ #undef _syscall3 -+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ LSS_BODY(3, type, name, arg1, arg2, arg3); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ -+ type4, arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_BODY(4, type, name, arg1, arg2, arg3, arg4); \ -+ } -+ #undef _syscall5 -+ #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ -+ type4, arg4, type5, arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5); \ -+ } -+ #undef _syscall6 -+ #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ -+ type4, arg4, type5, arg5, type6, arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ -+ } -+ /* clone function adapted from glibc 2.3.6 clone.S */ -+ /* TODO(csilvers): consider wrapping some args up in a struct, like we -+ * do for i386's _syscall6, so we can compile successfully on gcc 2.95 -+ */ -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ long __ret, __err; -+ { -+ register int (*__fn)(void *) __asm__ ("r8") = fn; -+ register void *__cstack __asm__ ("r4") = child_stack; -+ register int __flags __asm__ ("r3") = flags; -+ register void * __arg __asm__ ("r9") = arg; -+ register int * __ptidptr __asm__ ("r5") = parent_tidptr; -+ register void * __newtls __asm__ ("r6") = newtls; -+ register int * __ctidptr __asm__ ("r7") = child_tidptr; -+ __asm__ __volatile__( -+ /* check for fn == NULL -+ * and child_stack == NULL -+ */ -+ "cmpwi cr0, %6, 0\n\t" -+ "cmpwi cr1, %7, 0\n\t" -+ "cror cr0*4+eq, cr1*4+eq, cr0*4+eq\n\t" -+ "beq- cr0, 1f\n\t" -+ -+ /* set up stack frame for child */ -+ "clrrwi %7, %7, 4\n\t" -+ "li 0, 0\n\t" -+ "stwu 0, -16(%7)\n\t" -+ -+ /* fn, arg, child_stack are saved across the syscall: r28-30 */ -+ "mr 28, %6\n\t" -+ "mr 29, %7\n\t" -+ "mr 27, %9\n\t" -+ -+ /* syscall */ -+ "li 0, %4\n\t" -+ /* flags already in r3 -+ * child_stack already in r4 -+ * ptidptr already in r5 -+ * newtls already in r6 -+ * ctidptr already in r7 -+ */ -+ "sc\n\t" -+ -+ /* Test if syscall was successful */ -+ "cmpwi cr1, 3, 0\n\t" -+ "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" -+ "bne- cr1, 1f\n\t" -+ -+ /* Do the function call */ -+ "mtctr 28\n\t" -+ "mr 3, 27\n\t" -+ "bctrl\n\t" -+ -+ /* Call _exit(r3) */ -+ "li 0, %5\n\t" -+ "sc\n\t" -+ -+ /* Return to parent */ -+ "1:\n" -+ "mfcr %1\n\t" -+ "mr %0, 3\n\t" -+ : "=r" (__ret), "=r" (__err) -+ : "0" (-1), "1" (EINVAL), -+ "i" (__NR_clone), "i" (__NR_exit), -+ "r" (__fn), "r" (__cstack), "r" (__flags), -+ "r" (__arg), "r" (__ptidptr), "r" (__newtls), -+ "r" (__ctidptr) -+ : "cr0", "cr1", "memory", "ctr", -+ "r0", "r29", "r27", "r28"); -+ } -+ LSS_RETURN(int, __ret, __err); -+ } -+ #elif defined(__s390__) -+ #undef LSS_REG -+ #define LSS_REG(r, a) register unsigned long __r##r __asm__("r"#r) = (unsigned long) a -+ #undef LSS_BODY -+ #define LSS_BODY(type, name, args...) \ -+ register unsigned long __nr __asm__("r1") \ -+ = (unsigned long)(__NR_##name); \ -+ register long __res_r2 __asm__("r2"); \ -+ long __res; \ -+ __asm__ __volatile__ \ -+ ("svc 0\n\t" \ -+ : "=d"(__res_r2) \ -+ : "d"(__nr), ## args \ -+ : "memory"); \ -+ __res = __res_r2; \ -+ LSS_RETURN(type, __res) -+ #undef _syscall0 -+ #define _syscall0(type, name) \ -+ type LSS_NAME(name)(void) { \ -+ LSS_BODY(type, name); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type, name, type1, arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_REG(2, arg1); \ -+ LSS_BODY(type, name, "0"(__r2)); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type, name, type1, arg1, type2, arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ LSS_REG(2, arg1); LSS_REG(3, arg2); \ -+ LSS_BODY(type, name, "0"(__r2), "d"(__r3)); \ -+ } -+ #undef _syscall3 -+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ -+ LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4)); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ -+ type4, arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \ -+ type4 arg4) { \ -+ LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ -+ LSS_REG(5, arg4); \ -+ LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \ -+ "d"(__r5)); \ -+ } -+ #undef _syscall5 -+ #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ -+ type4, arg4, type5, arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \ -+ type4 arg4, type5 arg5) { \ -+ LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ -+ LSS_REG(5, arg4); LSS_REG(6, arg5); \ -+ LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \ -+ "d"(__r5), "d"(__r6)); \ -+ } -+ #undef _syscall6 -+ #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ -+ type4, arg4, type5, arg5, type6, arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, \ -+ type4 arg4, type5 arg5, type6 arg6) { \ -+ LSS_REG(2, arg1); LSS_REG(3, arg2); LSS_REG(4, arg3); \ -+ LSS_REG(5, arg4); LSS_REG(6, arg5); LSS_REG(7, arg6); \ -+ LSS_BODY(type, name, "0"(__r2), "d"(__r3), "d"(__r4), \ -+ "d"(__r5), "d"(__r6), "d"(__r7)); \ -+ } -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ long __ret; -+ { -+ register int (*__fn)(void *) __asm__ ("r1") = fn; -+ register void *__cstack __asm__ ("r2") = child_stack; -+ register int __flags __asm__ ("r3") = flags; -+ register void *__arg __asm__ ("r0") = arg; -+ register int *__ptidptr __asm__ ("r4") = parent_tidptr; -+ register void *__newtls __asm__ ("r6") = newtls; -+ register int *__ctidptr __asm__ ("r5") = child_tidptr; -+ __asm__ __volatile__ ( -+ #ifndef __s390x__ -+ /* arg already in r0 */ -+ "ltr %4, %4\n\t" /* check fn, which is already in r1 */ -+ "jz 1f\n\t" /* NULL function pointer, return -EINVAL */ -+ "ltr %5, %5\n\t" /* check child_stack, which is already in r2 */ -+ "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */ -+ /* flags already in r3 */ -+ /* parent_tidptr already in r4 */ -+ /* child_tidptr already in r5 */ -+ /* newtls already in r6 */ -+ "svc %2\n\t" /* invoke clone syscall */ -+ "ltr %0,%%r2\n\t" /* load return code into __ret and test */ -+ "jnz 1f\n\t" /* return to parent if non-zero */ -+ /* start child thread */ -+ "lr %%r2, %7\n\t" /* set first parameter to void *arg */ -+ "ahi %%r15, -96\n\t" /* make room on the stack for the save area */ -+ "xc 0(4,%%r15), 0(%%r15)\n\t" -+ "basr %%r14, %4\n\t" /* jump to fn */ -+ "svc %3\n" /* invoke exit syscall */ -+ "1:\n" -+ #else -+ /* arg already in r0 */ -+ "ltgr %4, %4\n\t" /* check fn, which is already in r1 */ -+ "jz 1f\n\t" /* NULL function pointer, return -EINVAL */ -+ "ltgr %5, %5\n\t" /* check child_stack, which is already in r2 */ -+ "jz 1f\n\t" /* NULL stack pointer, return -EINVAL */ -+ /* flags already in r3 */ -+ /* parent_tidptr already in r4 */ -+ /* child_tidptr already in r5 */ -+ /* newtls already in r6 */ -+ "svc %2\n\t" /* invoke clone syscall */ -+ "ltgr %0, %%r2\n\t" /* load return code into __ret and test */ -+ "jnz 1f\n\t" /* return to parent if non-zero */ -+ /* start child thread */ -+ "lgr %%r2, %7\n\t" /* set first parameter to void *arg */ -+ "aghi %%r15, -160\n\t" /* make room on the stack for the save area */ -+ "xc 0(8,%%r15), 0(%%r15)\n\t" -+ "basr %%r14, %4\n\t" /* jump to fn */ -+ "svc %3\n" /* invoke exit syscall */ -+ "1:\n" -+ #endif -+ : "=r" (__ret) -+ : "0" (-EINVAL), "i" (__NR_clone), "i" (__NR_exit), -+ "d" (__fn), "d" (__cstack), "d" (__flags), "d" (__arg), -+ "d" (__ptidptr), "d" (__newtls), "d" (__ctidptr) -+ : "cc", "r14", "memory" -+ ); -+ } -+ LSS_RETURN(int, __ret); -+ } -+ #elif defined(__riscv) && __riscv_xlen == 64 -+ #undef LSS_REG -+ #define LSS_REG(r,a) register int64_t __r##r __asm__("a"#r) = (int64_t)a -+ #undef LSS_BODY -+ #define LSS_BODY(type,name,args...) \ -+ register int64_t __res_a0 __asm__("a0"); \ -+ register int64_t __a7 __asm__("a7") = __NR_##name; \ -+ int64_t __res; \ -+ __asm__ __volatile__ ("scall\n" \ -+ : "=r"(__res_a0) \ -+ : "r"(__a7) , ## args \ -+ : "memory"); \ -+ __res = __res_a0; \ -+ LSS_RETURN(type, __res) -+ #undef _syscall0 -+ #define _syscall0(type, name) \ -+ type LSS_NAME(name)(void) { \ -+ LSS_BODY(type, name); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type, name, type1, arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type, name, type1, arg1, type2, arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ -+ } -+ #undef _syscall3 -+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ -+ } -+ #undef _syscall5 -+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4)); \ -+ } -+ #undef _syscall6 -+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4), "r"(__r5)); \ -+ } -+ -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ int64_t __res; -+ { -+ register int64_t __res_a0 __asm__("a0"); -+ register uint64_t __flags __asm__("a0") = flags; -+ register void *__stack __asm__("a1") = child_stack; -+ register void *__ptid __asm__("a2") = parent_tidptr; -+ register void *__tls __asm__("a3") = newtls; -+ register int *__ctid __asm__("a4") = child_tidptr; -+ __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be -+ * used by the child. -+ */ -+ "addi %2,%2,-16\n" -+ "sd %1, 0(%2)\n" -+ "sd %4, 8(%2)\n" -+ -+ /* %a0 = syscall(%a0 = flags, -+ * %a1 = child_stack, -+ * %a2 = parent_tidptr, -+ * %a3 = newtls, -+ * %a4 = child_tidptr) -+ */ -+ "li a7, %8\n" -+ "scall\n" -+ -+ /* if (%a0 != 0) -+ * return %a0; -+ */ -+ "bnez %0, 1f\n" -+ -+ /* In the child, now. Call "fn(arg)". -+ */ -+ "ld a1, 0(sp)\n" -+ "ld a0, 8(sp)\n" -+ "jalr a1\n" -+ -+ /* Call _exit(%a0). -+ */ -+ "li a7, %9\n" -+ "scall\n" -+ "1:\n" -+ : "=r" (__res_a0) -+ : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), -+ "r"(__ptid), "r"(__tls), "r"(__ctid), -+ "i"(__NR_clone), "i"(__NR_exit) -+ : "cc", "memory"); -+ __res = __res_a0; -+ } -+ LSS_RETURN(int, __res); -+ } -+ #elif defined(__e2k__) -+ -+ #undef _LSS_BODY -+ #define _LSS_BODY(nr, type, name, ...) \ -+ register unsigned long long __res; \ -+ __asm__ __volatile__ \ -+ ( \ -+ "{\n\t" \ -+ " sdisp %%ctpr1, 0x3\n\t" \ -+ " addd, s 0x0, %[sys_num], %%b[0]\n\t" \ -+ LSS_BODY_ASM##nr \ -+ "}\n\t" \ -+ "{\n\t" \ -+ " call %%ctpr1, wbs = %#\n\t" \ -+ "}\n\t" \ -+ "{\n\t" \ -+ " addd, s 0x0, %%b[0], %[res]\n\t" \ -+ "}\n\t" \ -+ : [res] "=r" (__res) \ -+ : \ -+ LSS_BODY_ARG##nr(__VA_ARGS__) \ -+ [sys_num] "ri" (__NR_##name) \ -+ : "ctpr1", "ctpr2", "ctpr3", \ -+ "b[0]", "b[1]", "b[2]", "b[3]", \ -+ "b[4]", "b[5]", "b[6]", "b[7]" \ -+ ); \ -+ LSS_RETURN(type, __res); -+ -+ #undef LSS_BODY -+ #define LSS_BODY(nr, type, name, args...) \ -+ _LSS_BODY(nr, type, name, ## args) -+ -+ #undef LSS_BODY_ASM0 -+ #undef LSS_BODY_ASM1 -+ #undef LSS_BODY_ASM2 -+ #undef LSS_BODY_ASM3 -+ #undef LSS_BODY_ASM4 -+ #undef LSS_BODY_ASM5 -+ #undef LSS_BODY_ASM6 -+ -+ #define LSS_BODY_ASM0 -+ #define LSS_BODY_ASM1 LSS_BODY_ASM0 \ -+ " addd, s 0x0, %[arg1], %%b[1]\n\t" -+ #define LSS_BODY_ASM2 LSS_BODY_ASM1 \ -+ " addd, s 0x0, %[arg2], %%b[2]\n\t" -+ #define LSS_BODY_ASM3 LSS_BODY_ASM2 \ -+ " addd, s 0x0, %[arg3], %%b[3]\n\t" -+ #define LSS_BODY_ASM4 LSS_BODY_ASM3 \ -+ " addd, s 0x0, %[arg4], %%b[4]\n\t" -+ #define LSS_BODY_ASM5 LSS_BODY_ASM4 \ -+ " addd, s 0x0, %[arg5], %%b[5]\n\t" -+ #define LSS_BODY_ASM6 LSS_BODY_ASM5 \ -+ "}\n\t" \ -+ "{\n\t" \ -+ " addd, s 0x0, %[arg6], %%b[6]\n\t" -+ -+ #undef LSS_SYSCALL_ARG -+ #define LSS_SYSCALL_ARG(a) ((unsigned long long)(uintptr_t)(a)) -+ -+ #undef LSS_BODY_ARG0 -+ #undef LSS_BODY_ARG1 -+ #undef LSS_BODY_ARG2 -+ #undef LSS_BODY_ARG3 -+ #undef LSS_BODY_ARG4 -+ #undef LSS_BODY_ARG5 -+ #undef LSS_BODY_ARG6 -+ -+ #define LSS_BODY_ARG0() -+ #define LSS_BODY_ARG1(_arg1) \ -+ [arg1] "ri" LSS_SYSCALL_ARG(_arg1), -+ #define LSS_BODY_ARG2(_arg1, _arg2) \ -+ LSS_BODY_ARG1(_arg1) \ -+ [arg2] "ri" LSS_SYSCALL_ARG(_arg2), -+ #define LSS_BODY_ARG3(_arg1, _arg2, _arg3) \ -+ LSS_BODY_ARG2(_arg1, _arg2) \ -+ [arg3] "ri" LSS_SYSCALL_ARG(_arg3), -+ #define LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \ -+ LSS_BODY_ARG3(_arg1, _arg2, _arg3) \ -+ [arg4] "ri" LSS_SYSCALL_ARG(_arg4), -+ #define LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \ -+ LSS_BODY_ARG4(_arg1, _arg2, _arg3, _arg4) \ -+ [arg5] "ri" LSS_SYSCALL_ARG(_arg5), -+ #define LSS_BODY_ARG6(_arg1, _arg2, _arg3, _arg4, _arg5, _arg6) \ -+ LSS_BODY_ARG5(_arg1, _arg2, _arg3, _arg4, _arg5) \ -+ [arg6] "ri" LSS_SYSCALL_ARG(_arg6), -+ -+ #undef _syscall0 -+ #define _syscall0(type, name) \ -+ type LSS_NAME(name)(void) { \ -+ LSS_BODY(0, type, name); \ -+ } -+ -+ #undef _syscall1 -+ #define _syscall1(type, name, type1, arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_BODY(1, type, name, arg1) \ -+ } -+ -+ #undef _syscall2 -+ #define _syscall2(type, name, type1, arg1, type2, arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ LSS_BODY(2, type, name, arg1, arg2) \ -+ } -+ -+ #undef _syscall3 -+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ LSS_BODY(3, type, name, arg1, arg2, arg3) \ -+ } -+ -+ #undef _syscall4 -+ #define _syscall4(type, name, type1, arg1, type2, arg2, type3, arg3, \ -+ type4, arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_BODY(4, type, name, arg1, arg2, arg3, arg4) \ -+ } -+ -+ #undef _syscall5 -+ #define _syscall5(type, name, type1, arg1, type2, arg2, type3, arg3, \ -+ type4, arg4, type5, arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_BODY(5, type, name, arg1, arg2, arg3, arg4, arg5) \ -+ } -+ -+ #undef _syscall6 -+ #define _syscall6(type, name, type1, arg1, type2, arg2, type3, arg3, \ -+ type4, arg4, type5, arg5, type6, arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ LSS_BODY(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6) \ -+ } -+ -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ unsigned long long __res; -+ -+ __asm__ __volatile__ ( -+ "{\n\t" -+ " addd,s 0x0, %[nr_clone], %%b[0]\n\t" -+ " addd,s 0x0, %[flags], %%db[1]\n\t" -+ " addd,s 0x0, %[child_stack], %%db[2]\n\t" -+ " addd,s 0x0, %[parent_tidptr], %%db[3]\n\t" -+ " addd,s 0x0, %[child_tidptr], %%db[4]\n\t" -+ " addd,s 0x0, %[newtls], %%db[5]\n\t" -+ "}\n\t" -+ /* if (fn == NULL) -+ * return -EINVAL; -+ */ -+ -+ "{\n\t" -+ " disp %%ctpr1, .L1\n\t" -+ "}\n\t" -+ "{\n\t" -+ " cmpesb,s 0x0, %[fn], %%pred0\n\t" -+ "}\n\t" -+ "{\n\t" -+ " ct %%ctpr1 ? %%pred0\n\t" -+ "}\n\t" -+ -+ /* if (child_stack == NULL) -+ * return -EINVAL; -+ */ -+ "{\n\t" -+ " cmpesb,s 0x0, %%db[2], %%pred0\n\t" -+ "}\n\t" -+ "{\n\t" -+ " ct %%ctpr1 ? %%pred0\n\t" -+ "}\n\t" -+ -+ /* b[0] = syscall(%b[0] = __NR_clone, -+ * %db[1] = flags, -+ * %db[2] = child_stack, -+ * %db[3] = parent_tidptr, -+ * %db[4] = child_tidptr, -+ * %db[5] = newtls) -+ */ -+ "{\n\t" -+ " sdisp %%ctpr1, 0x3\n\t" -+ "}\n\t" -+ "{\n\t" -+ " call %%ctpr1, wbs = %#\n\t" -+ "}\n\t" -+ -+ /* if (%[b0] != 0) -+ * return %b[0]; -+ */ -+ "{\n\t" -+ " disp %%ctpr1, .L2\n\t" -+ " cmpesb,s 0x0, %%b[0], %%pred0\n\t" -+ "}\n\t" -+ "{\n\t" -+ " ct %%ctpr1 ? ~%%pred0\n\t" -+ "}\n\t" -+ /* In the child, now. Call "fn(arg)". -+ */ -+ -+ "{\n\t" -+ " movtd,s %[fn], %%ctpr1\n\t" -+ "}\n\t" -+ "{\n\t" -+ " addd,s 0x0, %[arg], %%db[0]\n\t" -+ "}\n\t" -+ "{\n\t" -+ " call %%ctpr1, wbs = %#\n\t" -+ "}\n\t" -+ /* Call _exit(%b[0]). -+ */ -+ -+ "{\n\t" -+ " sdisp %%ctpr1, 0x3\n\t" -+ " addd,s 0x0, %%b[0], %%b[1]\n\t" -+ "}\n\t" -+ "{\n\t" -+ " addd,s 0x0, %[nr_exit], %%b[0]\n\t" -+ "}\n\t" -+ "{\n\t" -+ " call %%ctpr1, wbs = %#\n\t" -+ "}\n\t" -+ "{\n\t" -+ " disp %%ctpr1, .L2\n\t" -+ " adds,s 0x0, 0x0, %%b[0]\n\t" -+ "}\n\t" -+ "{\n\t" -+ " ct %%ctpr1\n\t" -+ "}\n\t" -+ ".L1:\n\t" -+ "{\n\t" -+ " addd,s 0x0, %[einval], %%b[0]\n\t" -+ "}\n\t" -+ ".L2:\n\t" -+ "{\n\t" -+ " addd,s 0x0, %%b[0], %[res]\n\t" -+ "}\n\t" -+ : [res] "=r" LSS_SYSCALL_ARG(__res) -+ : [nr_clone] "ri" LSS_SYSCALL_ARG(__NR_clone) -+ [arg] "ri" LSS_SYSCALL_ARG(arg) -+ [nr_exit] "ri" LSS_SYSCALL_ARG(__NR_exit) -+ [flags] "ri" LSS_SYSCALL_ARG(flags) -+ [child_stack] "ri" LSS_SYSCALL_ARG(child_stack) -+ [parent_tidptr] "ri" -+ LSS_SYSCALL_ARG(parent_tidptr) -+ [newtls] "ri" LSS_SYSCALL_ARG(newtls) -+ [child_tidptr] "ri" -+ LSS_SYSCALL_ARG(child_tidptr) -+ [fn] "ri" LSS_SYSCALL_ARG(fn) -+ [einval] "ri" LSS_SYSCALL_ARG(-EINVAL) -+ : "ctpr1", "b[0]", "b[1]", "b[2]", "b[3]", -+ "b[4]", "b[5]", "pred0"); -+ LSS_RETURN(int, __res); -+ } -+ #elif defined(__loongarch_lp64) -+ /* Most definitions of _syscallX() neglect to mark "memory" as being -+ * clobbered. This causes problems with compilers, that do a better job -+ * at optimizing across __asm__ calls. -+ * So, we just have to redefine all of the _syscallX() macros. -+ */ -+ #undef LSS_REG -+ #define LSS_REG(ar,a) register int64_t __r##ar __asm__("a"#ar) = (int64_t)a -+ /* syscall is like subroutine calls, all caller-saved registers may be -+ * clobbered, we should add them to the |Clobbers| list. -+ * a0 is not included because it's in the output list. -+ */ -+ #define LSS_SYSCALL_CLOBBERS "t0", "t1", "t2", "t3", "t4", "t5", "t6", \ -+ "t7", "t8", "memory" -+ #undef LSS_BODY -+ #define LSS_BODY(type,name,args...) \ -+ register int64_t __res_a0 __asm__("a0"); \ -+ register int64_t __a7 __asm__("a7") = __NR_##name; \ -+ int64_t __res; \ -+ __asm__ __volatile__ ("syscall 0x0\n" \ -+ : "=r"(__res_a0) \ -+ : "r"(__a7), ## args \ -+ : LSS_SYSCALL_CLOBBERS); \ -+ __res = __res_a0; \ -+ LSS_RETURN(type, __res) -+ #undef _syscall0 -+ #define _syscall0(type, name) \ -+ type LSS_NAME(name)(void) { \ -+ LSS_BODY(type, name); \ -+ } -+ #undef _syscall1 -+ #define _syscall1(type, name, type1, arg1) \ -+ type LSS_NAME(name)(type1 arg1) { \ -+ LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \ -+ } -+ #undef _syscall2 -+ #define _syscall2(type, name, type1, arg1, type2, arg2) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \ -+ } -+ #undef _syscall3 -+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \ -+ } -+ #undef _syscall4 -+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \ -+ } -+ #undef _syscall5 -+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4)); \ -+ } -+ #undef _syscall6 -+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ -+ type5,arg5,type6,arg6) \ -+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ -+ type5 arg5, type6 arg6) { \ -+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \ -+ LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \ -+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \ -+ "r"(__r4), "r"(__r5)); \ -+ } -+ -+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack, -+ int flags, void *arg, int *parent_tidptr, -+ void *newtls, int *child_tidptr) { -+ int64_t __res; -+ { -+ register int64_t __res_a0 __asm__("a0"); -+ register uint64_t __flags __asm__("a0") = flags; -+ register void *__stack __asm__("a1") = child_stack; -+ register void *__ptid __asm__("a2") = parent_tidptr; -+ register void *__tls __asm__("a3") = newtls; -+ register int *__ctid __asm__("a4") = child_tidptr; -+ __asm__ __volatile__(/* Push "arg" and "fn" onto the stack that will be -+ * used by the child. -+ */ -+ "addi.d %2, %2, -16\n" -+ "st.d %1, %2, 8\n" -+ "st.d %4, %2, 0\n" -+ -+ /* %a0 = syscall(%a0 = flags, -+ * %a1 = child_stack, -+ * %a2 = parent_tidptr, -+ * %a3 = newtls, -+ * %a4 = child_tidptr) -+ */ -+ "li.d $a7, %8\n" -+ "syscall 0x0\n" -+ -+ /* if (%a0 != 0) -+ * return %a0; -+ */ -+ "bnez $a0, 1f\n" -+ -+ /* In the child, now. Call "fn(arg)". -+ */ -+ "ld.d $a0, $sp, 0\n" -+ "ld.d $a1, $sp, 8\n" -+ "addi.d $sp, $sp, 16\n" -+ "jirl $ra, $a1, 0\n" -+ -+ /* Call _exit(%a0). -+ */ -+ "li.d $a7, %9\n" -+ "syscall 0x0\n" -+ "1:\n" -+ : "=r" (__res_a0) -+ : "r"(fn), "r"(__stack), "r"(__flags), "r"(arg), -+ "r"(__ptid), "r"(__tls), "r"(__ctid), -+ "i"(__NR_clone), "i"(__NR_exit) -+ : "a7", LSS_SYSCALL_CLOBBERS); -+ __res = __res_a0; -+ } -+ LSS_RETURN(int, __res); -+ } -+ -+ #endif -+ #define __NR__exit __NR_exit -+ #define __NR__gettid __NR_gettid -+ #define __NR__mremap __NR_mremap -+ LSS_INLINE _syscall1(void *, brk, void *, e) -+ LSS_INLINE _syscall1(int, chdir, const char *,p) -+ LSS_INLINE _syscall1(int, close, int, f) -+ LSS_INLINE _syscall2(int, clock_getres, int, c, -+ struct kernel_timespec*, t) -+ LSS_INLINE _syscall2(int, clock_gettime, int, c, -+ struct kernel_timespec*, t) -+ LSS_INLINE _syscall1(int, dup, int, f) -+ #if defined(__NR_dup2) -+ // dup2 is polyfilled below when not available. -+ LSS_INLINE _syscall2(int, dup2, int, s, -+ int, d) -+ #endif -+ #if defined(__NR_dup3) -+ LSS_INLINE _syscall3(int, dup3, int, s, int, d, int, f) -+ #endif -+ LSS_INLINE _syscall3(int, execve, const char*, f, -+ const char*const*,a,const char*const*, e) -+ LSS_INLINE _syscall1(int, _exit, int, e) -+ LSS_INLINE _syscall1(int, exit_group, int, e) -+ LSS_INLINE _syscall3(int, fcntl, int, f, -+ int, c, long, a) -+ #if defined(__NR_fork) -+ // fork is polyfilled below when not available. -+ LSS_INLINE _syscall0(pid_t, fork) -+ #endif -+ #if defined(__NR_fstat) -+ LSS_INLINE _syscall2(int, fstat, int, f, -+ struct kernel_stat*, b) -+ #endif -+ LSS_INLINE _syscall2(int, fstatfs, int, f, -+ struct kernel_statfs*, b) -+ #if defined(__x86_64__) -+ /* Need to make sure off_t isn't truncated to 32-bits under x32. */ -+ LSS_INLINE int LSS_NAME(ftruncate)(int f, off_t l) { -+ LSS_BODY(2, int, ftruncate, LSS_SYSCALL_ARG(f), (uint64_t)(l)); -+ } -+ #else -+ LSS_INLINE _syscall2(int, ftruncate, int, f, -+ off_t, l) -+ #endif -+ LSS_INLINE _syscall6(int, futex, int*, u, -+ int, o, int, v, -+ struct kernel_timespec*, t, -+ int*, u2, int, v2) -+ LSS_INLINE _syscall3(int, getdents, int, f, -+ struct kernel_dirent*, d, int, c) -+ LSS_INLINE _syscall3(int, getdents64, int, f, -+ struct kernel_dirent64*, d, int, c) -+ LSS_INLINE _syscall0(gid_t, getegid) -+ LSS_INLINE _syscall0(uid_t, geteuid) -+ LSS_INLINE _syscall2(int, getitimer, int, w, -+ struct kernel_itimerval*, c) -+ #if defined(__NR_getpgrp) -+ LSS_INLINE _syscall0(pid_t, getpgrp) -+ #endif -+ LSS_INLINE _syscall0(pid_t, getpid) -+ LSS_INLINE _syscall0(pid_t, getppid) -+ LSS_INLINE _syscall2(int, getpriority, int, a, -+ int, b) -+ LSS_INLINE _syscall3(int, getresgid, gid_t *, r, -+ gid_t *, e, gid_t *, s) -+ LSS_INLINE _syscall3(int, getresuid, uid_t *, r, -+ uid_t *, e, uid_t *, s) -+ #if defined(__NR_getrlimit) -+ LSS_INLINE _syscall2(int, getrlimit, int, r, -+ struct kernel_rlimit*, l) -+ #endif -+ LSS_INLINE _syscall1(pid_t, getsid, pid_t, p) -+ LSS_INLINE _syscall0(pid_t, _gettid) -+ LSS_INLINE _syscall2(pid_t, gettimeofday, struct kernel_timeval*, t, -+ void*, tz) -+ LSS_INLINE _syscall5(int, setxattr, const char *,p, -+ const char *, n, const void *,v, -+ size_t, s, int, f) -+ LSS_INLINE _syscall5(int, lsetxattr, const char *,p, -+ const char *, n, const void *,v, -+ size_t, s, int, f) -+ LSS_INLINE _syscall4(ssize_t, getxattr, const char *,p, -+ const char *, n, void *, v, size_t, s) -+ LSS_INLINE _syscall4(ssize_t, lgetxattr, const char *,p, -+ const char *, n, void *, v, size_t, s) -+ LSS_INLINE _syscall3(ssize_t, listxattr, const char *,p, -+ char *, l, size_t, s) -+ LSS_INLINE _syscall3(ssize_t, llistxattr, const char *,p, -+ char *, l, size_t, s) -+ LSS_INLINE _syscall3(int, ioctl, int, d, -+ int, r, void *, a) -+ LSS_INLINE _syscall2(int, ioprio_get, int, which, -+ int, who) -+ LSS_INLINE _syscall3(int, ioprio_set, int, which, -+ int, who, int, ioprio) -+ LSS_INLINE _syscall2(int, kill, pid_t, p, -+ int, s) -+ #if defined(__x86_64__) -+ /* Need to make sure off_t isn't truncated to 32-bits under x32. */ -+ LSS_INLINE off_t LSS_NAME(lseek)(int f, off_t o, int w) { -+ _LSS_BODY(3, off_t, lseek, off_t, LSS_SYSCALL_ARG(f), (uint64_t)(o), -+ LSS_SYSCALL_ARG(w)); -+ } -+ #else -+ LSS_INLINE _syscall3(off_t, lseek, int, f, -+ off_t, o, int, w) -+ #endif -+ LSS_INLINE _syscall2(int, munmap, void*, s, -+ size_t, l) -+ LSS_INLINE _syscall6(long, move_pages, pid_t, p, -+ unsigned long, n, void **,g, int *, d, -+ int *, s, int, f) -+ LSS_INLINE _syscall3(int, mprotect, const void *,a, -+ size_t, l, int, p) -+ LSS_INLINE _syscall5(void*, _mremap, void*, o, -+ size_t, os, size_t, ns, -+ unsigned long, f, void *, a) -+ #if defined(__NR_open) -+ // open is polyfilled below when not available. -+ LSS_INLINE _syscall3(int, open, const char*, p, -+ int, f, int, m) -+ #endif -+ #if defined(__NR_poll) -+ // poll is polyfilled below when not available. -+ LSS_INLINE _syscall3(int, poll, struct kernel_pollfd*, u, -+ unsigned int, n, int, t) -+ #endif -+ #if defined(__NR_ppoll) -+ LSS_INLINE _syscall5(int, ppoll, struct kernel_pollfd *, u, -+ unsigned int, n, const struct kernel_timespec *, t, -+ const struct kernel_sigset_t *, sigmask, size_t, s) -+ #endif -+ LSS_INLINE _syscall5(int, prctl, int, option, -+ unsigned long, arg2, -+ unsigned long, arg3, -+ unsigned long, arg4, -+ unsigned long, arg5) -+ LSS_INLINE _syscall4(long, ptrace, int, r, -+ pid_t, p, void *, a, void *, d) -+ #if defined(__NR_quotactl) -+ // Defined on x86_64 / i386 only -+ LSS_INLINE _syscall4(int, quotactl, int, cmd, const char *, special, -+ int, id, caddr_t, addr) -+ #endif -+ LSS_INLINE _syscall3(ssize_t, read, int, f, -+ void *, b, size_t, c) -+ #if defined(__NR_readlink) -+ // readlink is polyfilled below when not available. -+ LSS_INLINE _syscall3(int, readlink, const char*, p, -+ char*, b, size_t, s) -+ #endif -+ #if defined(__NR_readlinkat) -+ LSS_INLINE _syscall4(int, readlinkat, int, d, const char *, p, char *, b, -+ size_t, s) -+ #endif -+ LSS_INLINE _syscall4(int, rt_sigaction, int, s, -+ const struct kernel_sigaction*, a, -+ struct kernel_sigaction*, o, size_t, c) -+ LSS_INLINE _syscall2(int, rt_sigpending, struct kernel_sigset_t *, s, -+ size_t, c) -+ LSS_INLINE _syscall4(int, rt_sigprocmask, int, h, -+ const struct kernel_sigset_t*, s, -+ struct kernel_sigset_t*, o, size_t, c) -+ LSS_INLINE _syscall2(int, rt_sigsuspend, -+ const struct kernel_sigset_t*, s, size_t, c) -+ LSS_INLINE _syscall4(int, rt_sigtimedwait, const struct kernel_sigset_t*, s, -+ siginfo_t*, i, const struct timespec*, t, size_t, c) -+ LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p, -+ unsigned int, l, unsigned long *, m) -+ LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p, -+ unsigned int, l, unsigned long *, m) -+ LSS_INLINE _syscall0(int, sched_yield) -+ LSS_INLINE _syscall1(long, set_tid_address, int *, t) -+ LSS_INLINE _syscall1(int, setfsgid, gid_t, g) -+ LSS_INLINE _syscall1(int, setfsuid, uid_t, u) -+ LSS_INLINE _syscall1(int, setuid, uid_t, u) -+ LSS_INLINE _syscall1(int, setgid, gid_t, g) -+ LSS_INLINE _syscall3(int, setitimer, int, w, -+ const struct kernel_itimerval*, n, -+ struct kernel_itimerval*, o) -+ LSS_INLINE _syscall2(int, setpgid, pid_t, p, -+ pid_t, g) -+ LSS_INLINE _syscall3(int, setpriority, int, a, -+ int, b, int, p) -+ LSS_INLINE _syscall3(int, setresgid, gid_t, r, -+ gid_t, e, gid_t, s) -+ LSS_INLINE _syscall3(int, setresuid, uid_t, r, -+ uid_t, e, uid_t, s) -+ #if defined(__NR_setrlimit) -+ LSS_INLINE _syscall2(int, setrlimit, int, r, -+ const struct kernel_rlimit*, l) -+ #endif -+ LSS_INLINE _syscall0(pid_t, setsid) -+ LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s, -+ const stack_t*, o) -+ #if defined(__NR_sigreturn) -+ LSS_INLINE _syscall1(int, sigreturn, unsigned long, u) -+ #endif -+ #if defined(__NR_stat) -+ // stat and lstat are polyfilled below when not available. -+ LSS_INLINE _syscall2(int, stat, const char*, f, -+ struct kernel_stat*, b) -+ #endif -+ #if defined(__NR_lstat) -+ LSS_INLINE _syscall2(int, lstat, const char*, f, -+ struct kernel_stat*, b) -+ #endif -+ LSS_INLINE _syscall2(int, statfs, const char*, f, -+ struct kernel_statfs*, b) -+ LSS_INLINE _syscall3(int, tgkill, pid_t, p, -+ pid_t, t, int, s) -+ LSS_INLINE _syscall2(int, tkill, pid_t, p, -+ int, s) -+ #if defined(__NR_unlink) -+ // unlink is polyfilled below when not available. -+ LSS_INLINE _syscall1(int, unlink, const char*, f) -+ #endif -+ LSS_INLINE _syscall3(ssize_t, write, int, f, -+ const void *, b, size_t, c) -+ LSS_INLINE _syscall3(ssize_t, writev, int, f, -+ const struct kernel_iovec*, v, size_t, c) -+ #if defined(__NR_getcpu) -+ LSS_INLINE _syscall3(long, getcpu, unsigned *, cpu, -+ unsigned *, node, void *, unused) -+ #endif -+ #if defined(__NR_fadvise64) -+ #if defined(__x86_64__) -+ /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ -+ LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, loff_t len, -+ int advice) { -+ LSS_BODY(4, int, fadvise64, LSS_SYSCALL_ARG(fd), (uint64_t)(offset), -+ (uint64_t)(len), LSS_SYSCALL_ARG(advice)); -+ } -+ #else -+ LSS_INLINE _syscall4(int, fadvise64, -+ int, fd, loff_t, offset, loff_t, len, int, advice) -+ #endif -+ #elif defined(__i386__) -+ #define __NR__fadvise64_64 __NR_fadvise64_64 -+ LSS_INLINE _syscall6(int, _fadvise64_64, int, fd, -+ unsigned, offset_lo, unsigned, offset_hi, -+ unsigned, len_lo, unsigned, len_hi, -+ int, advice) -+ -+ LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, -+ loff_t len, int advice) { -+ return LSS_NAME(_fadvise64_64)(fd, -+ (unsigned)offset, (unsigned)(offset >>32), -+ (unsigned)len, (unsigned)(len >> 32), -+ advice); -+ } -+ -+ #elif defined(__s390__) && !defined(__s390x__) -+ #define __NR__fadvise64_64 __NR_fadvise64_64 -+ struct kernel_fadvise64_64_args { -+ int fd; -+ long long offset; -+ long long len; -+ int advice; -+ }; -+ -+ LSS_INLINE _syscall1(int, _fadvise64_64, -+ struct kernel_fadvise64_64_args *args) -+ -+ LSS_INLINE int LSS_NAME(fadvise64)(int fd, loff_t offset, -+ loff_t len, int advice) { -+ struct kernel_fadvise64_64_args args = { fd, offset, len, advice }; -+ return LSS_NAME(_fadvise64_64)(&args); -+ } -+ #endif -+ #if defined(__NR_fallocate) -+ #if defined(__x86_64__) -+ /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ -+ LSS_INLINE int LSS_NAME(fallocate)(int f, int mode, loff_t offset, -+ loff_t len) { -+ LSS_BODY(4, int, fallocate, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(mode), -+ (uint64_t)(offset), (uint64_t)(len)); -+ } -+ #elif (defined(__i386__) || (defined(__s390__) && !defined(__s390x__)) \ -+ || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) \ -+ || (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) \ -+ || defined(__PPC__)) -+ #define __NR__fallocate __NR_fallocate -+ LSS_INLINE _syscall6(int, _fallocate, int, fd, -+ int, mode, -+ unsigned, offset_lo, unsigned, offset_hi, -+ unsigned, len_lo, unsigned, len_hi) -+ -+ LSS_INLINE int LSS_NAME(fallocate)(int fd, int mode, -+ loff_t offset, loff_t len) { -+ union { loff_t off; unsigned w[2]; } o = { offset }, l = { len }; -+ return LSS_NAME(_fallocate)(fd, mode, o.w[0], o.w[1], l.w[0], l.w[1]); -+ } -+ #else -+ LSS_INLINE _syscall4(int, fallocate, -+ int, f, int, mode, loff_t, offset, loff_t, len) -+ #endif -+ #endif -+ #if defined(__NR_getrandom) -+ LSS_INLINE _syscall3(ssize_t, getrandom, void*, buffer, size_t, length, -+ unsigned int, flags) -+ #endif -+ #if defined(__NR_newfstatat) -+ LSS_INLINE _syscall4(int, newfstatat, int, d, -+ const char *, p, -+ struct kernel_stat*, b, int, f) -+ #endif -+ #if defined(__NR_statx) -+ LSS_INLINE _syscall5(int, statx, int, d, -+ const char *, p, -+ int, f, int, m, -+ struct kernel_statx*, b) -+ #endif -+ #if defined(__x86_64__) || defined(__s390x__) -+ LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, -+ gid_t *egid, -+ gid_t *sgid) { -+ return LSS_NAME(getresgid)(rgid, egid, sgid); -+ } -+ -+ LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, -+ uid_t *euid, -+ uid_t *suid) { -+ return LSS_NAME(getresuid)(ruid, euid, suid); -+ } -+ -+ LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { -+ return LSS_NAME(setfsgid)(gid); -+ } -+ -+ LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { -+ return LSS_NAME(setfsuid)(uid); -+ } -+ -+ LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { -+ return LSS_NAME(setresgid)(rgid, egid, sgid); -+ } -+ -+ LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { -+ return LSS_NAME(setresuid)(ruid, euid, suid); -+ } -+ -+ LSS_INLINE int LSS_NAME(sigaction)(int signum, -+ const struct kernel_sigaction *act, -+ struct kernel_sigaction *oldact) { -+ #if defined(__x86_64__) -+ /* On x86_64, the kernel requires us to always set our own -+ * SA_RESTORER in order to be able to return from a signal handler. -+ * This function must have a "magic" signature that the "gdb" -+ * (and maybe the kernel?) can recognize. -+ */ -+ if (act != NULL && !(act->sa_flags & SA_RESTORER)) { -+ struct kernel_sigaction a = *act; -+ a.sa_flags |= SA_RESTORER; -+ a.sa_restorer = LSS_NAME(restore_rt)(); -+ return LSS_NAME(rt_sigaction)(signum, &a, oldact, -+ (KERNEL_NSIG+7)/8); -+ } else -+ #endif -+ return LSS_NAME(rt_sigaction)(signum, act, oldact, -+ (KERNEL_NSIG+7)/8); -+ } -+ -+ LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { -+ return LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); -+ } -+ -+ LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { -+ return LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); -+ } -+ #endif -+ #if defined(__NR_rt_sigprocmask) -+ LSS_INLINE int LSS_NAME(sigprocmask)(int how, -+ const struct kernel_sigset_t *set, -+ struct kernel_sigset_t *oldset) { -+ return LSS_NAME(rt_sigprocmask)(how, set, oldset, (KERNEL_NSIG+7)/8); -+ } -+ #endif -+ #if defined(__NR_rt_sigtimedwait) -+ LSS_INLINE int LSS_NAME(sigtimedwait)(const struct kernel_sigset_t *set, -+ siginfo_t *info, -+ const struct timespec *timeout) { -+ return LSS_NAME(rt_sigtimedwait)(set, info, timeout, (KERNEL_NSIG+7)/8); -+ } -+ #endif -+ #if defined(__NR_wait4) -+ LSS_INLINE _syscall4(pid_t, wait4, pid_t, p, -+ int*, s, int, o, -+ struct kernel_rusage*, r) -+ #endif -+ #if defined(__NR_openat) -+ LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m) -+ #endif -+ #if defined(__NR_unlinkat) -+ LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f) -+ #endif -+ #if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ -+ (defined(__s390__) && !defined(__s390x__)) -+ #define __NR__getresgid32 __NR_getresgid32 -+ #define __NR__getresuid32 __NR_getresuid32 -+ #define __NR__setfsgid32 __NR_setfsgid32 -+ #define __NR__setfsuid32 __NR_setfsuid32 -+ #define __NR__setresgid32 __NR_setresgid32 -+ #define __NR__setresuid32 __NR_setresuid32 -+#if defined(__ARM_EABI__) -+ LSS_INLINE _syscall2(int, ugetrlimit, int, r, -+ struct kernel_rlimit*, l) -+#endif -+ LSS_INLINE _syscall3(int, _getresgid32, gid_t *, r, -+ gid_t *, e, gid_t *, s) -+ LSS_INLINE _syscall3(int, _getresuid32, uid_t *, r, -+ uid_t *, e, uid_t *, s) -+ LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f) -+ LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f) -+ LSS_INLINE _syscall3(int, _setresgid32, gid_t, r, -+ gid_t, e, gid_t, s) -+ LSS_INLINE _syscall3(int, _setresuid32, uid_t, r, -+ uid_t, e, uid_t, s) -+ -+ LSS_INLINE int LSS_NAME(getresgid32)(gid_t *rgid, -+ gid_t *egid, -+ gid_t *sgid) { -+ int rc; -+ if ((rc = LSS_NAME(_getresgid32)(rgid, egid, sgid)) < 0 && -+ LSS_ERRNO == ENOSYS) { -+ if ((rgid == NULL) || (egid == NULL) || (sgid == NULL)) { -+ return EFAULT; -+ } -+ // Clear the high bits first, since getresgid only sets 16 bits -+ *rgid = *egid = *sgid = 0; -+ rc = LSS_NAME(getresgid)(rgid, egid, sgid); -+ } -+ return rc; -+ } -+ -+ LSS_INLINE int LSS_NAME(getresuid32)(uid_t *ruid, -+ uid_t *euid, -+ uid_t *suid) { -+ int rc; -+ if ((rc = LSS_NAME(_getresuid32)(ruid, euid, suid)) < 0 && -+ LSS_ERRNO == ENOSYS) { -+ if ((ruid == NULL) || (euid == NULL) || (suid == NULL)) { -+ return EFAULT; -+ } -+ // Clear the high bits first, since getresuid only sets 16 bits -+ *ruid = *euid = *suid = 0; -+ rc = LSS_NAME(getresuid)(ruid, euid, suid); -+ } -+ return rc; -+ } -+ -+ LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) { -+ int rc; -+ if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 && -+ LSS_ERRNO == ENOSYS) { -+ if ((unsigned int)gid & ~0xFFFFu) { -+ rc = EINVAL; -+ } else { -+ rc = LSS_NAME(setfsgid)(gid); -+ } -+ } -+ return rc; -+ } -+ -+ LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) { -+ int rc; -+ if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 && -+ LSS_ERRNO == ENOSYS) { -+ if ((unsigned int)uid & ~0xFFFFu) { -+ rc = EINVAL; -+ } else { -+ rc = LSS_NAME(setfsuid)(uid); -+ } -+ } -+ return rc; -+ } -+ -+ LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) { -+ int rc; -+ if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 && -+ LSS_ERRNO == ENOSYS) { -+ if ((unsigned int)rgid & ~0xFFFFu || -+ (unsigned int)egid & ~0xFFFFu || -+ (unsigned int)sgid & ~0xFFFFu) { -+ rc = EINVAL; -+ } else { -+ rc = LSS_NAME(setresgid)(rgid, egid, sgid); -+ } -+ } -+ return rc; -+ } -+ -+ LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) { -+ int rc; -+ if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 && -+ LSS_ERRNO == ENOSYS) { -+ if ((unsigned int)ruid & ~0xFFFFu || -+ (unsigned int)euid & ~0xFFFFu || -+ (unsigned int)suid & ~0xFFFFu) { -+ rc = EINVAL; -+ } else { -+ rc = LSS_NAME(setresuid)(ruid, euid, suid); -+ } -+ } -+ return rc; -+ } -+ #endif -+ LSS_INLINE int LSS_NAME(sigemptyset)(struct kernel_sigset_t *set) { -+ memset(&set->sig, 0, sizeof(set->sig)); -+ return 0; -+ } -+ -+ LSS_INLINE int LSS_NAME(sigfillset)(struct kernel_sigset_t *set) { -+ memset(&set->sig, -1, sizeof(set->sig)); -+ return 0; -+ } -+ -+ LSS_INLINE int LSS_NAME(sigaddset)(struct kernel_sigset_t *set, -+ int signum) { -+ if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) { -+ LSS_ERRNO = EINVAL; -+ return -1; -+ } else { -+ set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] -+ |= 1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0]))); -+ return 0; -+ } -+ } -+ -+ LSS_INLINE int LSS_NAME(sigdelset)(struct kernel_sigset_t *set, -+ int signum) { -+ if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) { -+ LSS_ERRNO = EINVAL; -+ return -1; -+ } else { -+ set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] -+ &= ~(1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0])))); -+ return 0; -+ } -+ } -+ -+ LSS_INLINE int LSS_NAME(sigismember)(struct kernel_sigset_t *set, -+ int signum) { -+ if (signum < 1 || (size_t)signum > (8*sizeof(set->sig))) { -+ LSS_ERRNO = EINVAL; -+ return -1; -+ } else { -+ return !!(set->sig[(size_t)(signum - 1)/(8*sizeof(set->sig[0]))] & -+ (1UL << ((size_t)(signum - 1) % (8*sizeof(set->sig[0]))))); -+ } -+ } -+ #if defined(__i386__) || \ -+ defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ -+ (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ -+ defined(__PPC__) || \ -+ (defined(__s390__) && !defined(__s390x__)) || defined(__e2k__) -+ #define __NR__sigaction __NR_sigaction -+ #define __NR__sigpending __NR_sigpending -+ #define __NR__sigsuspend __NR_sigsuspend -+ #define __NR__socketcall __NR_socketcall -+ LSS_INLINE _syscall2(int, fstat64, int, f, -+ struct kernel_stat64 *, b) -+ LSS_INLINE _syscall5(int, _llseek, uint, fd, -+ unsigned long, hi, unsigned long, lo, -+ loff_t *, res, uint, wh) -+#if defined(__s390__) && !defined(__s390x__) -+ /* On s390, mmap2() arguments are passed in memory. */ -+ LSS_INLINE void* LSS_NAME(_mmap2)(void *s, size_t l, int p, int f, int d, -+ off_t o) { -+ unsigned long buf[6] = { (unsigned long) s, (unsigned long) l, -+ (unsigned long) p, (unsigned long) f, -+ (unsigned long) d, (unsigned long) o }; -+ LSS_REG(2, buf); -+ LSS_BODY(void*, mmap2, "0"(__r2)); -+ } -+#else -+ #define __NR__mmap2 __NR_mmap2 -+ LSS_INLINE _syscall6(void*, _mmap2, void*, s, -+ size_t, l, int, p, -+ int, f, int, d, -+ off_t, o) -+#endif -+ LSS_INLINE _syscall3(int, _sigaction, int, s, -+ const struct kernel_old_sigaction*, a, -+ struct kernel_old_sigaction*, o) -+ LSS_INLINE _syscall1(int, _sigpending, unsigned long*, s) -+ #ifdef __PPC__ -+ LSS_INLINE _syscall1(int, _sigsuspend, unsigned long, s) -+ #else -+ LSS_INLINE _syscall3(int, _sigsuspend, const void*, a, -+ int, b, -+ unsigned long, s) -+ #endif -+ LSS_INLINE _syscall2(int, stat64, const char *, p, -+ struct kernel_stat64 *, b) -+ -+ LSS_INLINE int LSS_NAME(sigaction)(int signum, -+ const struct kernel_sigaction *act, -+ struct kernel_sigaction *oldact) { -+ int old_errno = LSS_ERRNO; -+ int rc; -+ struct kernel_sigaction a; -+ if (act != NULL) { -+ a = *act; -+ #ifdef __i386__ -+ /* On i386, the kernel requires us to always set our own -+ * SA_RESTORER when using realtime signals. Otherwise, it does not -+ * know how to return from a signal handler. This function must have -+ * a "magic" signature that the "gdb" (and maybe the kernel?) can -+ * recognize. -+ * Apparently, a SA_RESTORER is implicitly set by the kernel, when -+ * using non-realtime signals. -+ * -+ * TODO: Test whether ARM needs a restorer -+ */ -+ if (!(a.sa_flags & SA_RESTORER)) { -+ a.sa_flags |= SA_RESTORER; -+ a.sa_restorer = (a.sa_flags & SA_SIGINFO) -+ ? LSS_NAME(restore_rt)() : LSS_NAME(restore)(); -+ } -+ #endif -+ } -+ rc = LSS_NAME(rt_sigaction)(signum, act ? &a : act, oldact, -+ (KERNEL_NSIG+7)/8); -+ if (rc < 0 && LSS_ERRNO == ENOSYS) { -+ struct kernel_old_sigaction oa, ooa, *ptr_a = &oa, *ptr_oa = &ooa; -+ if (!act) { -+ ptr_a = NULL; -+ } else { -+ oa.sa_handler_ = act->sa_handler_; -+ memcpy(&oa.sa_mask, &act->sa_mask, sizeof(oa.sa_mask)); -+ #ifndef __mips__ -+ oa.sa_restorer = act->sa_restorer; -+ #endif -+ oa.sa_flags = act->sa_flags; -+ } -+ if (!oldact) { -+ ptr_oa = NULL; -+ } -+ LSS_ERRNO = old_errno; -+ rc = LSS_NAME(_sigaction)(signum, ptr_a, ptr_oa); -+ if (rc == 0 && oldact) { -+ if (act) { -+ memcpy(oldact, act, sizeof(*act)); -+ } else { -+ memset(oldact, 0, sizeof(*oldact)); -+ } -+ oldact->sa_handler_ = ptr_oa->sa_handler_; -+ oldact->sa_flags = ptr_oa->sa_flags; -+ memcpy(&oldact->sa_mask, &ptr_oa->sa_mask, sizeof(ptr_oa->sa_mask)); -+ #ifndef __mips__ -+ oldact->sa_restorer = ptr_oa->sa_restorer; -+ #endif -+ } -+ } -+ return rc; -+ } -+ -+ LSS_INLINE int LSS_NAME(sigpending)(struct kernel_sigset_t *set) { -+ int old_errno = LSS_ERRNO; -+ int rc = LSS_NAME(rt_sigpending)(set, (KERNEL_NSIG+7)/8); -+ if (rc < 0 && LSS_ERRNO == ENOSYS) { -+ LSS_ERRNO = old_errno; -+ LSS_NAME(sigemptyset)(set); -+ rc = LSS_NAME(_sigpending)(&set->sig[0]); -+ } -+ return rc; -+ } -+ -+ LSS_INLINE int LSS_NAME(sigsuspend)(const struct kernel_sigset_t *set) { -+ int olderrno = LSS_ERRNO; -+ int rc = LSS_NAME(rt_sigsuspend)(set, (KERNEL_NSIG+7)/8); -+ if (rc < 0 && LSS_ERRNO == ENOSYS) { -+ LSS_ERRNO = olderrno; -+ rc = LSS_NAME(_sigsuspend)( -+ #ifndef __PPC__ -+ set, 0, -+ #endif -+ set->sig[0]); -+ } -+ return rc; -+ } -+ #endif -+ #if defined(__i386__) || \ -+ defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ -+ (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ -+ defined(__PPC__) || \ -+ (defined(__s390__) && !defined(__s390x__)) -+ /* On these architectures, implement mmap() with mmap2(). */ -+ LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, -+ int64_t o) { -+ if (o % 4096) { -+ LSS_ERRNO = EINVAL; -+ return (void *) -1; -+ } -+ return LSS_NAME(_mmap2)(s, l, p, f, d, (o / 4096)); -+ } -+ #elif defined(__s390x__) -+ /* On s390x, mmap() arguments are passed in memory. */ -+ LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, -+ int64_t o) { -+ unsigned long buf[6] = { (unsigned long) s, (unsigned long) l, -+ (unsigned long) p, (unsigned long) f, -+ (unsigned long) d, (unsigned long) o }; -+ LSS_REG(2, buf); -+ LSS_BODY(void*, mmap, "0"(__r2)); -+ } -+ #elif defined(__x86_64__) -+ /* Need to make sure __off64_t isn't truncated to 32-bits under x32. */ -+ LSS_INLINE void* LSS_NAME(mmap)(void *s, size_t l, int p, int f, int d, -+ int64_t o) { -+ LSS_BODY(6, void*, mmap, LSS_SYSCALL_ARG(s), LSS_SYSCALL_ARG(l), -+ LSS_SYSCALL_ARG(p), LSS_SYSCALL_ARG(f), -+ LSS_SYSCALL_ARG(d), (uint64_t)(o)); -+ } -+ #else -+ /* Remaining 64-bit architectures. */ -+ LSS_INLINE _syscall6(void*, mmap, void*, addr, size_t, length, int, prot, -+ int, flags, int, fd, int64_t, offset) -+ #endif -+ #if defined(__PPC__) -+ #undef LSS_SC_LOADARGS_0 -+ #define LSS_SC_LOADARGS_0(dummy...) -+ #undef LSS_SC_LOADARGS_1 -+ #define LSS_SC_LOADARGS_1(arg1) \ -+ __sc_4 = (unsigned long) (arg1) -+ #undef LSS_SC_LOADARGS_2 -+ #define LSS_SC_LOADARGS_2(arg1, arg2) \ -+ LSS_SC_LOADARGS_1(arg1); \ -+ __sc_5 = (unsigned long) (arg2) -+ #undef LSS_SC_LOADARGS_3 -+ #define LSS_SC_LOADARGS_3(arg1, arg2, arg3) \ -+ LSS_SC_LOADARGS_2(arg1, arg2); \ -+ __sc_6 = (unsigned long) (arg3) -+ #undef LSS_SC_LOADARGS_4 -+ #define LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4) \ -+ LSS_SC_LOADARGS_3(arg1, arg2, arg3); \ -+ __sc_7 = (unsigned long) (arg4) -+ #undef LSS_SC_LOADARGS_5 -+ #define LSS_SC_LOADARGS_5(arg1, arg2, arg3, arg4, arg5) \ -+ LSS_SC_LOADARGS_4(arg1, arg2, arg3, arg4); \ -+ __sc_8 = (unsigned long) (arg5) -+ #undef LSS_SC_BODY -+ #define LSS_SC_BODY(nr, type, opt, args...) \ -+ long __sc_ret, __sc_err; \ -+ { \ -+ register unsigned long __sc_0 __asm__ ("r0") = __NR_socketcall; \ -+ register unsigned long __sc_3 __asm__ ("r3") = opt; \ -+ register unsigned long __sc_4 __asm__ ("r4"); \ -+ register unsigned long __sc_5 __asm__ ("r5"); \ -+ register unsigned long __sc_6 __asm__ ("r6"); \ -+ register unsigned long __sc_7 __asm__ ("r7"); \ -+ register unsigned long __sc_8 __asm__ ("r8"); \ -+ LSS_SC_LOADARGS_##nr(args); \ -+ __asm__ __volatile__ \ -+ ("stwu 1, -48(1)\n\t" \ -+ "stw 4, 20(1)\n\t" \ -+ "stw 5, 24(1)\n\t" \ -+ "stw 6, 28(1)\n\t" \ -+ "stw 7, 32(1)\n\t" \ -+ "stw 8, 36(1)\n\t" \ -+ "addi 4, 1, 20\n\t" \ -+ "sc\n\t" \ -+ "mfcr %0" \ -+ : "=&r" (__sc_0), \ -+ "=&r" (__sc_3), "=&r" (__sc_4), \ -+ "=&r" (__sc_5), "=&r" (__sc_6), \ -+ "=&r" (__sc_7), "=&r" (__sc_8) \ -+ : LSS_ASMINPUT_##nr \ -+ : "cr0", "ctr", "memory"); \ -+ __sc_ret = __sc_3; \ -+ __sc_err = __sc_0; \ -+ } \ -+ LSS_RETURN(type, __sc_ret, __sc_err) -+ -+ LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, -+ int flags){ -+ LSS_SC_BODY(3, ssize_t, 17, s, msg, flags); -+ } -+ -+ LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, -+ const struct kernel_msghdr *msg, -+ int flags) { -+ LSS_SC_BODY(3, ssize_t, 16, s, msg, flags); -+ } -+ -+ // TODO(csilvers): why is this ifdef'ed out? -+#if 0 -+ LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, -+ int flags, -+ const struct kernel_sockaddr *to, -+ unsigned int tolen) { -+ LSS_BODY(6, ssize_t, 11, s, buf, len, flags, to, tolen); -+ } -+#endif -+ -+ LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { -+ LSS_SC_BODY(2, int, 13, s, how); -+ } -+ -+ LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { -+ LSS_SC_BODY(3, int, 1, domain, type, protocol); -+ } -+ -+ LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, -+ int sv[2]) { -+ LSS_SC_BODY(4, int, 8, d, type, protocol, sv); -+ } -+ #endif -+ #if defined(__NR_recvmsg) -+ LSS_INLINE _syscall3(ssize_t, recvmsg, int, s, struct kernel_msghdr*, msg, -+ int, flags) -+ #endif -+ #if defined(__NR_sendmsg) -+ LSS_INLINE _syscall3(ssize_t, sendmsg, int, s, const struct kernel_msghdr*, -+ msg, int, flags) -+ #endif -+ #if defined(__NR_sendto) -+ LSS_INLINE _syscall6(ssize_t, sendto, int, s, const void*, buf, size_t,len, -+ int, flags, const struct kernel_sockaddr*, to, -+ unsigned int, tolen) -+ #endif -+ #if defined(__NR_shutdown) -+ LSS_INLINE _syscall2(int, shutdown, int, s, int, how) -+ #endif -+ #if defined(__NR_socket) -+ LSS_INLINE _syscall3(int, socket, int, domain, int, type, int, protocol) -+ #endif -+ #if defined(__NR_socketpair) -+ LSS_INLINE _syscall4(int, socketpair, int, d, int, type, int, protocol, -+ int*, sv) -+ #endif -+ -+ #if defined(__NR_socketcall) -+ LSS_INLINE _syscall2(int, _socketcall, int, c, -+ va_list, a) -+ LSS_INLINE int LSS_NAME(socketcall)(int op, ...) { -+ int rc; -+ va_list ap; -+ va_start(ap, op); -+ rc = LSS_NAME(_socketcall)(op, ap); -+ va_end(ap); -+ return rc; -+ } -+ -+ # if !defined(__NR_recvmsg) -+ LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct kernel_msghdr *msg, -+ int flags){ -+ return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags); -+ } -+ # endif -+ # if !defined(__NR_sendmsg) -+ LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, -+ const struct kernel_msghdr *msg, -+ int flags) { -+ return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags); -+ } -+ # endif -+ # if !defined(__NR_sendto) -+ LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len, -+ int flags, -+ const struct kernel_sockaddr *to, -+ unsigned int tolen) { -+ return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen); -+ } -+ # endif -+ # if !defined(__NR_shutdown) -+ LSS_INLINE int LSS_NAME(shutdown)(int s, int how) { -+ return LSS_NAME(socketcall)(13, s, how); -+ } -+ # endif -+ # if !defined(__NR_socket) -+ LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) { -+ return LSS_NAME(socketcall)(1, domain, type, protocol); -+ } -+ # endif -+ # if !defined(__NR_socketpair) -+ LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol, -+ int sv[2]) { -+ return LSS_NAME(socketcall)(8, d, type, protocol, sv); -+ } -+ # endif -+ #endif -+ #if defined(__NR_fstatat64) -+ LSS_INLINE _syscall4(int, fstatat64, int, d, -+ const char *, p, -+ struct kernel_stat64 *, b, int, f) -+ #endif -+ #if defined(__NR_waitpid) -+ // waitpid is polyfilled below when not available. -+ LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p, -+ int*, s, int, o) -+ #endif -+ #if defined(__mips__) -+ /* sys_pipe() on MIPS has non-standard calling conventions, as it returns -+ * both file handles through CPU registers. -+ */ -+ LSS_INLINE int LSS_NAME(pipe)(int *p) { -+ register unsigned long __v0 __asm__("$2") = __NR_pipe; -+ register unsigned long __v1 __asm__("$3"); -+ register unsigned long __r7 __asm__("$7"); -+ __asm__ __volatile__ ("syscall\n" -+ : "=r"(__v0), "=r"(__v1), "=r" (__r7) -+ : "0"(__v0) -+ : "$8", "$9", "$10", "$11", "$12", -+ "$13", "$14", "$15", "$24", "$25", "memory"); -+ if (__r7) { -+ unsigned long __errnovalue = __v0; -+ LSS_ERRNO = __errnovalue; -+ return -1; -+ } else { -+ p[0] = __v0; -+ p[1] = __v1; -+ return 0; -+ } -+ } -+ #elif defined(__NR_pipe) -+ // pipe is polyfilled below when not available. -+ LSS_INLINE _syscall1(int, pipe, int *, p) -+ #endif -+ #if defined(__NR_pipe2) -+ LSS_INLINE _syscall2(int, pipe2, int *, pipefd, int, flags) -+ #endif -+ /* TODO(csilvers): see if ppc can/should support this as well */ -+ #if defined(__i386__) || defined(__ARM_ARCH_3__) || \ -+ defined(__ARM_EABI__) || \ -+ (defined(__mips__) && _MIPS_SIM != _MIPS_SIM_ABI64) || \ -+ (defined(__s390__) && !defined(__s390x__)) -+ #define __NR__statfs64 __NR_statfs64 -+ #define __NR__fstatfs64 __NR_fstatfs64 -+ LSS_INLINE _syscall3(int, _statfs64, const char*, p, -+ size_t, s,struct kernel_statfs64*, b) -+ LSS_INLINE _syscall3(int, _fstatfs64, int, f, -+ size_t, s,struct kernel_statfs64*, b) -+ LSS_INLINE int LSS_NAME(statfs64)(const char *p, -+ struct kernel_statfs64 *b) { -+ return LSS_NAME(_statfs64)(p, sizeof(*b), b); -+ } -+ LSS_INLINE int LSS_NAME(fstatfs64)(int f,struct kernel_statfs64 *b) { -+ return LSS_NAME(_fstatfs64)(f, sizeof(*b), b); -+ } -+ #endif -+ -+ LSS_INLINE int LSS_NAME(execv)(const char *path, const char *const argv[]) { -+ extern char **environ; -+ return LSS_NAME(execve)(path, argv, (const char *const *)environ); -+ } -+ -+ LSS_INLINE pid_t LSS_NAME(gettid)(void) { -+ pid_t tid = LSS_NAME(_gettid)(); -+ if (tid != -1) { -+ return tid; -+ } -+ return LSS_NAME(getpid)(); -+ } -+ -+ LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size, -+ size_t new_size, int flags, ...) { -+ va_list ap; -+ void *new_address, *rc; -+ va_start(ap, flags); -+ new_address = va_arg(ap, void *); -+ rc = LSS_NAME(_mremap)(old_address, old_size, new_size, -+ (unsigned long)flags, new_address); -+ va_end(ap); -+ return rc; -+ } -+ -+ LSS_INLINE long LSS_NAME(ptrace_detach)(pid_t pid) { -+ /* PTRACE_DETACH can sometimes forget to wake up the tracee and it -+ * then sends job control signals to the real parent, rather than to -+ * the tracer. We reduce the risk of this happening by starting a -+ * whole new time slice, and then quickly sending a SIGCONT signal -+ * right after detaching from the tracee. -+ * -+ * We use tkill to ensure that we only issue a wakeup for the thread being -+ * detached. Large multi threaded apps can take a long time in the kernel -+ * processing SIGCONT. -+ */ -+ long rc; -+ int err; -+ LSS_NAME(sched_yield)(); -+ rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0); -+ err = LSS_ERRNO; -+ LSS_NAME(tkill)(pid, SIGCONT); -+ /* Old systems don't have tkill */ -+ if (LSS_ERRNO == ENOSYS) -+ LSS_NAME(kill)(pid, SIGCONT); -+ LSS_ERRNO = err; -+ return rc; -+ } -+ -+ LSS_INLINE int LSS_NAME(raise)(int sig) { -+ return LSS_NAME(kill)(LSS_NAME(getpid)(), sig); -+ } -+ -+ LSS_INLINE int LSS_NAME(setpgrp)(void) { -+ return LSS_NAME(setpgid)(0, 0); -+ } -+ -+ #if defined(__x86_64__) -+ /* Need to make sure loff_t isn't truncated to 32-bits under x32. */ -+ LSS_INLINE ssize_t LSS_NAME(pread64)(int f, void *b, size_t c, loff_t o) { -+ LSS_BODY(4, ssize_t, pread64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), -+ LSS_SYSCALL_ARG(c), (uint64_t)(o)); -+ } -+ -+ LSS_INLINE ssize_t LSS_NAME(pwrite64)(int f, const void *b, size_t c, -+ loff_t o) { -+ LSS_BODY(4, ssize_t, pwrite64, LSS_SYSCALL_ARG(f), LSS_SYSCALL_ARG(b), -+ LSS_SYSCALL_ARG(c), (uint64_t)(o)); -+ } -+ -+ LSS_INLINE int LSS_NAME(readahead)(int f, loff_t o, size_t c) { -+ LSS_BODY(3, int, readahead, LSS_SYSCALL_ARG(f), (uint64_t)(o), -+ LSS_SYSCALL_ARG(c)); -+ } -+ #elif defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI64 -+ LSS_INLINE _syscall4(ssize_t, pread64, int, f, -+ void *, b, size_t, c, -+ loff_t, o) -+ LSS_INLINE _syscall4(ssize_t, pwrite64, int, f, -+ const void *, b, size_t, c, -+ loff_t, o) -+ LSS_INLINE _syscall3(int, readahead, int, f, -+ loff_t, o, unsigned, c) -+ #else -+ #define __NR__pread64 __NR_pread64 -+ #define __NR__pwrite64 __NR_pwrite64 -+ #define __NR__readahead __NR_readahead -+ #if defined(__ARM_EABI__) || defined(__mips__) -+ /* On ARM and MIPS, a 64-bit parameter has to be in an even-odd register -+ * pair. Hence these calls ignore their fourth argument (r3) so that their -+ * fifth and sixth make such a pair (r4,r5). -+ */ -+ #define LSS_LLARG_PAD 0, -+ LSS_INLINE _syscall6(ssize_t, _pread64, int, f, -+ void *, b, size_t, c, -+ unsigned, skip, unsigned, o1, unsigned, o2) -+ LSS_INLINE _syscall6(ssize_t, _pwrite64, int, f, -+ const void *, b, size_t, c, -+ unsigned, skip, unsigned, o1, unsigned, o2) -+ LSS_INLINE _syscall5(int, _readahead, int, f, -+ unsigned, skip, -+ unsigned, o1, unsigned, o2, size_t, c) -+ #else -+ #define LSS_LLARG_PAD -+ LSS_INLINE _syscall5(ssize_t, _pread64, int, f, -+ void *, b, size_t, c, unsigned, o1, -+ unsigned, o2) -+ LSS_INLINE _syscall5(ssize_t, _pwrite64, int, f, -+ const void *, b, size_t, c, unsigned, o1, -+ unsigned, o2) -+ LSS_INLINE _syscall4(int, _readahead, int, f, -+ unsigned, o1, unsigned, o2, size_t, c) -+ #endif -+ /* We force 64bit-wide parameters onto the stack, then access each -+ * 32-bit component individually. This guarantees that we build the -+ * correct parameters independent of the native byte-order of the -+ * underlying architecture. -+ */ -+ LSS_INLINE ssize_t LSS_NAME(pread64)(int fd, void *buf, size_t count, -+ loff_t off) { -+ union { loff_t off; unsigned arg[2]; } o = { off }; -+ return LSS_NAME(_pread64)(fd, buf, count, -+ LSS_LLARG_PAD o.arg[0], o.arg[1]); -+ } -+ LSS_INLINE ssize_t LSS_NAME(pwrite64)(int fd, const void *buf, -+ size_t count, loff_t off) { -+ union { loff_t off; unsigned arg[2]; } o = { off }; -+ return LSS_NAME(_pwrite64)(fd, buf, count, -+ LSS_LLARG_PAD o.arg[0], o.arg[1]); -+ } -+ LSS_INLINE int LSS_NAME(readahead)(int fd, loff_t off, size_t count) { -+ union { loff_t off; unsigned arg[2]; } o = { off }; -+ return LSS_NAME(_readahead)(fd, LSS_LLARG_PAD o.arg[0], o.arg[1], count); -+ } -+ #endif -+#endif -+ -+/* -+ * Polyfills for deprecated syscalls. -+ */ -+ -+#if !defined(__NR_dup2) -+ LSS_INLINE int LSS_NAME(dup2)(int s, int d) { -+ return LSS_NAME(dup3)(s, d, 0); -+ } -+#endif -+ -+#if !defined(__NR_open) -+ LSS_INLINE int LSS_NAME(open)(const char *pathname, int flags, int mode) { -+ return LSS_NAME(openat)(AT_FDCWD, pathname, flags, mode); -+ } -+#endif -+ -+#if !defined(__NR_unlink) -+ LSS_INLINE int LSS_NAME(unlink)(const char *pathname) { -+ return LSS_NAME(unlinkat)(AT_FDCWD, pathname, 0); -+ } -+#endif -+ -+#if !defined(__NR_readlink) -+ LSS_INLINE int LSS_NAME(readlink)(const char *pathname, char *buffer, -+ size_t size) { -+ return LSS_NAME(readlinkat)(AT_FDCWD, pathname, buffer, size); -+ } -+#endif -+ -+#if !defined(__NR_pipe) -+ LSS_INLINE int LSS_NAME(pipe)(int *pipefd) { -+ return LSS_NAME(pipe2)(pipefd, 0); -+ } -+#endif -+ -+#if !defined(__NR_poll) -+ LSS_INLINE int LSS_NAME(poll)(struct kernel_pollfd *fds, unsigned int nfds, -+ int timeout) { -+ struct kernel_timespec timeout_ts; -+ struct kernel_timespec *timeout_ts_p = NULL; -+ -+ if (timeout >= 0) { -+ timeout_ts.tv_sec = timeout / 1000; -+ timeout_ts.tv_nsec = (timeout % 1000) * 1000000; -+ timeout_ts_p = &timeout_ts; -+ } -+ return LSS_NAME(ppoll)(fds, nfds, timeout_ts_p, NULL, 0); -+ } -+#endif -+ -+#if defined(__NR_statx) -+ /* copy the contents of kernel_statx to the kernel_stat structure. */ -+ LSS_INLINE void LSS_NAME(cp_stat_statx)(struct kernel_stat *to, -+ struct kernel_statx *from) { -+ memset(to, 0, sizeof(struct kernel_stat)); -+ to->st_dev = (kernel_dev_t)((from->stx_dev_minor & 0xff) | -+ ((from->stx_dev_major & 0xfff) << 8) | -+ ((from->stx_dev_minor & ~0xffu) << 12)); -+ to->st_rdev = (kernel_dev_t)((from->stx_rdev_minor & 0xff) | -+ ((from->stx_rdev_major & 0xfff) << 8) | -+ ((from->stx_rdev_minor & ~0xffu) << 12)); -+ to->st_ino = (kernel_ino_t)from->stx_ino; -+ to->st_mode = (kernel_mode_t)from->stx_mode; -+ to->st_nlink = (kernel_nlink_t)from->stx_nlink; -+ to->st_uid = (kernel_uid_t)from->stx_uid; -+ to->st_gid = (kernel_gid_t)from->stx_gid; -+ to->st_atime_ = (kernel_time_t)(from->stx_atime.tv_sec); -+ to->st_atime_nsec_ = from->stx_atime.tv_nsec; -+ to->st_mtime_ = (kernel_time_t)(from->stx_mtime.tv_sec); -+ to->st_mtime_nsec_ = from->stx_mtime.tv_nsec; -+ to->st_ctime_ = (kernel_time_t)(from->stx_ctime.tv_sec); -+ to->st_ctime_nsec_ = from->stx_ctime.tv_nsec; -+ to->st_size = (kernel_off_t)(from->stx_size); -+ to->st_blocks = (kernel_blkcnt_t)(from->stx_blocks); -+ to->st_blksize = (kernel_blksize_t)from->stx_blksize; -+ } -+#endif -+ -+#if !defined(__NR_fstat) -+ LSS_INLINE int LSS_NAME(fstat)(int fd, -+ struct kernel_stat *buf) { -+ #if defined(__NR_newfstatat) -+ return LSS_NAME(newfstatat)(fd, "", buf, AT_EMPTY_PATH); -+ #elif defined(__NR_statx) -+ struct kernel_statx stx; -+ int flags = AT_NO_AUTOMOUNT | AT_EMPTY_PATH; -+ int mask = STATX_BASIC_STATS; -+ int res = LSS_NAME(statx)(fd, "", flags, mask, &stx); -+ LSS_NAME(cp_stat_statx)(buf, &stx); -+ return res; -+ #endif -+ } -+#endif -+ -+#if !defined(__NR_stat) -+ LSS_INLINE int LSS_NAME(stat)(const char *pathname, -+ struct kernel_stat *buf) { -+ #if defined(__NR_newfstatat) -+ return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, 0); -+ #elif defined(__NR_statx) -+ struct kernel_statx stx; -+ int flags = AT_NO_AUTOMOUNT | AT_STATX_SYNC_AS_STAT; -+ int mask = STATX_BASIC_STATS; -+ int res = LSS_NAME(statx)(AT_FDCWD, pathname, flags, mask, &stx); -+ LSS_NAME(cp_stat_statx)(buf, &stx); -+ return res; -+ #endif -+ } -+#endif -+ -+#if !defined(__NR_lstat) -+ LSS_INLINE int LSS_NAME(lstat)(const char *pathname, -+ struct kernel_stat *buf) { -+ #if defined(__NR_newfstatat) -+ return LSS_NAME(newfstatat)(AT_FDCWD, pathname, buf, AT_SYMLINK_NOFOLLOW); -+ #elif defined(__NR_statx) -+ struct kernel_statx stx; -+ int flags = AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW; -+ int mask = STATX_BASIC_STATS; -+ int res = LSS_NAME(statx)(AT_FDCWD, pathname, flags, mask, &stx); -+ LSS_NAME(cp_stat_statx)(buf, &stx); -+ return res; -+ #endif -+ } -+#endif -+ -+#if !defined(__NR_waitpid) -+ LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options) { -+ return LSS_NAME(wait4)(pid, status, options, 0); -+ } -+#endif -+ -+#if !defined(__NR_fork) -+// TODO: define this in an arch-independant way instead of inlining the clone -+// syscall body. -+ -+# if defined(__aarch64__) || defined(__riscv) || defined(__loongarch_lp64) -+ LSS_INLINE pid_t LSS_NAME(fork)(void) { -+ // No fork syscall on aarch64 - implement by means of the clone syscall. -+ // Note that this does not reset glibc's cached view of the PID/TID, so -+ // some glibc interfaces might go wrong in the forked subprocess. -+ int flags = SIGCHLD; -+ void *child_stack = NULL; -+ void *parent_tidptr = NULL; -+ void *newtls = NULL; -+ void *child_tidptr = NULL; -+ -+ LSS_REG(0, flags); -+ LSS_REG(1, child_stack); -+ LSS_REG(2, parent_tidptr); -+ LSS_REG(3, newtls); -+ LSS_REG(4, child_tidptr); -+ LSS_BODY(pid_t, clone, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), -+ "r"(__r4)); -+ } -+# elif defined(__x86_64__) -+ LSS_INLINE pid_t LSS_NAME(fork)(void) { -+ // Android disallows the fork syscall on x86_64 - implement by means of the -+ // clone syscall as above for aarch64. -+ int flags = SIGCHLD; -+ void *child_stack = NULL; -+ void *parent_tidptr = NULL; -+ void *newtls = NULL; -+ void *child_tidptr = NULL; -+ -+ LSS_BODY(5, pid_t, clone, LSS_SYSCALL_ARG(flags), -+ LSS_SYSCALL_ARG(child_stack), LSS_SYSCALL_ARG(parent_tidptr), -+ LSS_SYSCALL_ARG(newtls), LSS_SYSCALL_ARG(child_tidptr)); -+ } -+# else -+# error missing fork polyfill for this architecture -+# endif -+#endif -+ -+/* These restore the original values of these macros saved by the -+ * corresponding #pragma push_macro near the top of this file. */ -+#pragma pop_macro("stat64") -+#pragma pop_macro("fstat64") -+#pragma pop_macro("lstat64") -+#pragma pop_macro("pread64") -+#pragma pop_macro("pwrite64") -+#pragma pop_macro("getdents64") -+ -+#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS) -+} -+#endif -+ -+#endif -+#endif -\ No newline at end of file diff --git a/patches/0006-Fix-multipart-missing-CRLF.patch b/patches/0006-Fix-multipart-missing-CRLF.patch deleted file mode 100644 index 8772edb..0000000 --- a/patches/0006-Fix-multipart-missing-CRLF.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc -index bd48a233..cd12a24e 100644 ---- a/src/common/windows/http_upload.cc -+++ b/src/common/windows/http_upload.cc -@@ -536,7 +536,7 @@ namespace { - return false; - } - } -- request_body->append("--" + boundary_str + "--\r\n"); -+ request_body->append("\r\n--" + boundary_str + "--\r\n"); - return true; - } - } diff --git a/third_party/Patch b/third_party/Patch index 5fef224..1a3c2b0 100644 --- a/third_party/Patch +++ b/third_party/Patch @@ -36,10 +36,7 @@ git_dir = Normalize(os.path.join(builder.currentSourcePath, 'breakpad')) patches = AddFilesFromDir(os.path.join(builder.currentSourcePath, '..', 'patches'), [ "0001-Ignore-invalid-modules-rather-than-bailing-on-the-en.patch", "0002-Write-FUNC-records-instead-of-PUBLIC-for-ELF-symbols.patch", - "0003-Support-compilation-on-VS-2015.patch", - "0004-Fix-Linux-a-out-include.patch", - "0005-Add-LSS.patch", - "0006-Fix-multipart-missing-CRLF.patch" + "0003-Include-the-kernel-s-a.out.h-instead-of-glibc-s.patch" ]) # Reset the breakpad directory before applying patches diff --git a/third_party/breakpad b/third_party/breakpad index baa562b..69e9aad 160000 --- a/third_party/breakpad +++ b/third_party/breakpad @@ -1 +1 @@ -Subproject commit baa562ba435b01bf887ee71427256c40da7dcc49 +Subproject commit 69e9aada412e81575a95d0d94f4592fe1b8dfc15