Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
66d5f6a
[lldb] fix parallel module loading deadlock for Linux DYLD (#166480)
zhyty Nov 14, 2025
326d4e9
[SLP]Check if the copyable element is a sub instruciton with abs in i…
alexey-bataev Nov 14, 2025
21502bd
[lldb] Drop support for the Buffer Protocol (#168144)
JDevlieghere Nov 15, 2025
55f634c
[libcxx][Github] Attempt to Fix libcxx Container Push
boomanaiden154 Nov 15, 2025
94c384c
[lldb] Enforce Py_LIMITED_API in the SWIG typemaps (#168147)
JDevlieghere Nov 15, 2025
4eea157
[GlobalISel] Return byte offsets from computeValueLLTs (NFC) (#166747)
s-barannikov Nov 15, 2025
4530047
[lldb] Add the ability to load DWARF64 .debug_str_offsets tables for …
clayborg Nov 15, 2025
5305a53
[gn] port c29b29bb6a7f (_LIBCPP_ASSERTION_SEMANTIC_DEFAULT)
nico Nov 15, 2025
9036e23
[libc++] Apply `[[nodiscard]]` to `in/out_ptr` (#167097)
H-G-Hristov Nov 15, 2025
6214dcc
[Unwind][AArch64] Match sigreturn instructions in big endian (#167139)
hstk30-hw Nov 15, 2025
5442aa1
[RDF] Rename RegisterId field in RegisterRef Reg->Id. NFC (#168154)
topperc Nov 15, 2025
1f3e2c6
[gn] Let tablegen() add root_build_dir to include search path
nico Nov 15, 2025
7016d43
[NFC][SpecialCaseList] Convert `preprocess` into `LazyInit` (#167281)
vitalybuka Nov 15, 2025
321a97e
[AMDGPU] Delete some dead code (NFC) (#167891)
s-barannikov Nov 15, 2025
0fa6a67
AMDGPU: Use v_mov_b32 to implement divergent zext i32->i64 (#168166)
arsenm Nov 15, 2025
e7b41df
[SelectionDAGBuilder] Propagate fast-math flags to fpext (#167574)
mikolaj-pirog Nov 15, 2025
f8d65fd
[AArch64][GlobalISel] Improve lowering of vector fp16 fpext (#165554)
HolyMolyCowMan Nov 15, 2025
d8f6e10
AMDGPU: Use vgpr to implement divergent i32->i64 anyext (#168167)
arsenm Nov 15, 2025
9fecebf
AMDGPU: Consider isVGPRImm when forming constant from build_vector (#…
arsenm Nov 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/libcxx-build-containers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ jobs:

- name: Push the images
if: github.event_name == 'push'
run: docker compose push libcxx-linux-builder-base libcxx-linux-builder libcxx-android-builder
run: docker compose --file libcxx/utils/ci/docker/docker-compose.yml push libcxx-linux-builder-base libcxx-linux-builder libcxx-android-builder
env:
TAG: ${{ github.sha }}

# We create tarballs with the images and upload them as artifacts, since that's useful for testing
# the images when making changes.
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__memory/inout_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class inout_ptr_t {
};

template <class _Pointer = void, class _Smart, class... _Args>
_LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto inout_ptr(_Smart& __s, _Args&&... __args) {
using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
return std::inout_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...);
}
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__memory/out_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class out_ptr_t {
};

template <class _Pointer = void, class _Smart, class... _Args>
_LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) {
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto out_ptr(_Smart& __s, _Args&&... __args) {
using _Ptr = conditional_t<is_void_v<_Pointer>, __pointer_of_t<_Smart>, _Pointer>;
return std::out_ptr_t<_Smart, _Ptr, _Args&&...>(__s, std::forward<_Args>(__args)...);
}
Expand Down
29 changes: 29 additions & 0 deletions libcxx/test/libcxx/utilities/smartptr/nodiscard.verify.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// REQUIRES: std-at-least-c++23

// <memory>

// Check that functions are marked [[nodiscard]]

#include <memory>

#include "test_macros.h"

void test() {
#if TEST_STD_VER >= 23
{
std::unique_ptr<int> uPtr;
// [inout.ptr]
std::inout_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
// [out.ptr]
std::out_ptr(uPtr); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
}
#endif
}
17 changes: 16 additions & 1 deletion libunwind/src/UnwindCursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2865,6 +2865,21 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool isReturnAddress) {

#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) && \
defined(_LIBUNWIND_TARGET_AARCH64)

/*
* The linux sigreturn restorer stub will always have the form:
*
* d2801168 movz x8, #0x8b
* d4000001 svc #0x0
*/
#if defined(__AARCH64EB__)
#define MOVZ_X8_8B 0x681180d2
#define SVC_0 0x010000d4
#else
#define MOVZ_X8_8B 0xd2801168
#define SVC_0 0xd4000001
#endif

template <typename A, typename R>
bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
// Look for the sigreturn trampoline. The trampoline's body is two
Expand All @@ -2889,7 +2904,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
return false;
auto *instructions = reinterpret_cast<const uint32_t *>(pc);
// Look for instructions: mov x8, #0x8b; svc #0x0
if (instructions[0] != 0xd2801168 || instructions[1] != 0xd4000001)
if (instructions[0] != MOVZ_X8_8B || instructions[1] != SVC_0)
return false;

_info = {};
Expand Down
75 changes: 24 additions & 51 deletions lldb/bindings/python/python-typemaps.swig
Original file line number Diff line number Diff line change
Expand Up @@ -628,61 +628,34 @@ template <> bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
}
}

// These two pybuffer macros are copied out of swig/Lib/python/pybuffer.i,
// and fixed so they will not crash if PyObject_GetBuffer fails.
// https://github.com/swig/swig/issues/1640
//
// I've also moved the call to PyBuffer_Release to the end of the SWIG wrapper,
// doing it right away is not legal according to the python buffer protocol.
%inline %{
struct Py_buffer_RAII {
Py_buffer buffer = {};
Py_buffer_RAII(){};
Py_buffer &operator=(const Py_buffer_RAII &) = delete;
Py_buffer_RAII(const Py_buffer_RAII &) = delete;
~Py_buffer_RAII() {
if (buffer.obj)
PyBuffer_Release(&buffer);
}
};
%}

%define %pybuffer_mutable_binary(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
int res;
Py_ssize_t size = 0;
void *buf = 0;
res = PyObject_GetBuffer($input, &view.buffer, PyBUF_WRITABLE);
if (res < 0) {
PyErr_Clear();
%argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
}
size = view.buffer.len;
buf = view.buffer.buf;
$1 = ($1_ltype)buf;
$2 = ($2_ltype)(size / sizeof($*1_type));
}
%enddef

%define %pybuffer_binary(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE) (Py_buffer_RAII view) {
int res;
Py_ssize_t size = 0;
const void *buf = 0;
res = PyObject_GetBuffer($input, &view.buffer, PyBUF_CONTIG_RO);
if (res < 0) {
PyErr_Clear();
%argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
// Typemap for SBFile::Write.
%typemap(in) (const uint8_t *buf, size_t num_bytes) {
if (PythonByteArray::Check($input)) {
PythonByteArray bytearray(PyRefType::Borrowed, $input);
$1 = (uint8_t *)bytearray.GetBytes().data();
$2 = bytearray.GetSize();
} else if (PythonBytes::Check($input)) {
PythonBytes bytes(PyRefType::Borrowed, $input);
$1 = (uint8_t *)bytes.GetBytes().data();
$2 = bytes.GetSize();
} else {
PyErr_SetString(PyExc_ValueError, "Expecting a bytes or bytearray object");
SWIG_fail;
}
size = view.buffer.len;
buf = view.buffer.buf;
$1 = ($1_ltype)buf;
$2 = ($2_ltype)(size / sizeof($*1_type));
}
%enddef

%pybuffer_binary(const uint8_t *buf, size_t num_bytes);
%pybuffer_mutable_binary(uint8_t *buf, size_t num_bytes);
// Typemap for SBFile::Read.
%typemap(in) (uint8_t *buf, size_t num_bytes) {
if (PythonByteArray::Check($input)) {
PythonByteArray bytearray(PyRefType::Borrowed, $input);
$1 = (uint8_t *)bytearray.GetBytes().data();
$2 = bytearray.GetSize();
} else {
PyErr_SetString(PyExc_ValueError, "Expecting a bytearray");
SWIG_fail;
}
}

%typemap(in) (const char **symbol_name, uint32_t num_names) {
using namespace lldb_private;
Expand Down
7 changes: 5 additions & 2 deletions lldb/bindings/python/python-wrapper.swig
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,11 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallTypeScript(

PyObject *pfunc_impl = nullptr;

if (pyfunct_wrapper && *pyfunct_wrapper &&
PyFunction_Check(*pyfunct_wrapper)) {
if (pyfunct_wrapper && *pyfunct_wrapper
#ifndef Py_LIMITED_API
&& PyFunction_Check(*pyfunct_wrapper)
#endif
) {
pfunc_impl = (PyObject *)(*pyfunct_wrapper);
if (pfunc_impl->ob_refcnt == 1) {
Py_XDECREF(pfunc_impl);
Expand Down
5 changes: 5 additions & 0 deletions lldb/bindings/python/python.swig
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ except ImportError:
// Parameter types will be used in the autodoc string.
%feature("autodoc", "1");

// Include lldb-python first as it sets Py_LIMITED_API.
%begin %{
#include "../source/Plugins/ScriptInterpreter/Python/lldb-python.h"
%}

%pythoncode%{
import uuid
import re
Expand Down
6 changes: 6 additions & 0 deletions lldb/include/lldb/Core/ModuleList.h
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,12 @@ class ModuleList {
/// Atomically swaps the contents of this module list with \a other.
void Swap(ModuleList &other);

/// For each module in this ModuleList, preload its symbols.
///
/// \param[in] parallelize
/// If true, all modules will be preloaded in parallel.
void PreloadSymbols(bool parallelize) const;

protected:
// Class typedefs.
typedef std::vector<lldb::ModuleSP>
Expand Down
1 change: 1 addition & 0 deletions lldb/include/lldb/Target/DynamicLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ class DynamicLoader : public PluginInterface {
protected:
// Utility methods for derived classes

/// Find a module in the target that matches the given file.
lldb::ModuleSP FindModuleViaTarget(const FileSpec &file);

/// Checks to see if the target module has changed, updates the target
Expand Down
16 changes: 15 additions & 1 deletion lldb/include/lldb/Target/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -629,13 +629,20 @@ class Target : public std::enable_shared_from_this<Target>,
/// or identify a matching Module already present in the Target,
/// and return a shared pointer to it.
///
/// Note that this function previously also preloaded the module's symbols
/// depending on a setting. This function no longer does any module
/// preloading because that can potentially cause deadlocks when called in
/// parallel with this function.
///
/// \param[in] module_spec
/// The criteria that must be matched for the binary being loaded.
/// e.g. UUID, architecture, file path.
///
/// \param[in] notify
/// If notify is true, and the Module is new to this Target,
/// Target::ModulesDidLoad will be called.
/// Target::ModulesDidLoad will be called. See note in
/// Target::ModulesDidLoad about thread-safety with
/// Target::GetOrCreateModule.
/// If notify is false, it is assumed that the caller is adding
/// multiple Modules and will call ModulesDidLoad with the
/// full list at the end.
Expand Down Expand Up @@ -931,6 +938,13 @@ class Target : public std::enable_shared_from_this<Target>,
// the address of its previous instruction and return that address.
lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr);

/// This call may preload module symbols, and may do so in parallel depending
/// on the following target settings:
/// - TargetProperties::GetPreloadSymbols()
/// - TargetProperties::GetParallelModuleLoad()
///
/// Warning: if preloading is active and this is called in parallel with
/// Target::GetOrCreateModule, this may result in a ABBA deadlock situation.
void ModulesDidLoad(ModuleList &module_list);

void ModulesDidUnload(ModuleList &module_list, bool delete_locations);
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Core/DynamicLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ ModuleSP DynamicLoader::FindModuleViaTarget(const FileSpec &file) {
if (ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec))
return module_sp;

if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, false))
if (ModuleSP module_sp =
target.GetOrCreateModule(module_spec, /*notify=*/false))
return module_sp;

return nullptr;
Expand Down
20 changes: 20 additions & 0 deletions lldb/source/Core/ModuleList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "lldb/Core/ModuleList.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
Expand All @@ -28,6 +29,7 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/UUID.h"
#include "lldb/lldb-defines.h"
#include "llvm/Support/ThreadPool.h"

#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
Expand Down Expand Up @@ -1381,3 +1383,21 @@ void ModuleList::Swap(ModuleList &other) {
m_modules_mutex, other.m_modules_mutex);
m_modules.swap(other.m_modules);
}

void ModuleList::PreloadSymbols(bool parallelize) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);

if (!parallelize) {
for (const ModuleSP &module_sp : m_modules)
module_sp->PreloadSymbols();
return;
}

llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool());
for (const ModuleSP &module_sp : m_modules)
task_group.async([module_sp] {
if (module_sp)
module_sp->PreloadSymbols();
});
task_group.wait();
}
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,8 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
}

ModuleSP module_sp = LoadModuleAtAddress(
so_entry.file_spec, so_entry.link_addr, so_entry.base_addr, true);
so_entry.file_spec, so_entry.link_addr, so_entry.base_addr,
/*base_addr_is_offset=*/true);
if (!module_sp.get())
return;

Expand Down Expand Up @@ -726,9 +727,8 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
task_group.async(load_module_fn, *I);
task_group.wait();
} else {
for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) {
for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
load_module_fn(*I);
}
}

m_process->GetTarget().ModulesDidLoad(module_list);
Expand Down
35 changes: 25 additions & 10 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ void DWARFUnit::ExtractDIEsRWLocked() {
void DWARFUnit::SetDwoStrOffsetsBase() {
lldb::offset_t baseOffset = 0;

// Size of offset for .debug_str_offsets is same as DWARF offset byte size
// of the DWARFUnit as a default. We might override this if below if needed.
m_str_offset_size = m_header.getDwarfOffsetByteSize();

if (const llvm::DWARFUnitIndex::Entry *entry = m_header.getIndexEntry()) {
if (const auto *contribution =
entry->getContribution(llvm::DW_SECT_STR_OFFSETS))
Expand All @@ -357,14 +361,17 @@ void DWARFUnit::SetDwoStrOffsetsBase() {
}

if (GetVersion() >= 5) {
const DWARFDataExtractor &strOffsets =
GetSymbolFileDWARF().GetDWARFContext().getOrLoadStrOffsetsData();
uint64_t length = strOffsets.GetU32(&baseOffset);
if (length == 0xffffffff)
length = strOffsets.GetU64(&baseOffset);

const llvm::DWARFDataExtractor &strOffsets = GetSymbolFileDWARF()
.GetDWARFContext()
.getOrLoadStrOffsetsData()
.GetAsLLVMDWARF();

uint64_t length;
llvm::dwarf::DwarfFormat format;
std::tie(length, format) = strOffsets.getInitialLength(&baseOffset);
m_str_offset_size = format == llvm::dwarf::DwarfFormat::DWARF64 ? 8 : 4;
// Check version.
if (strOffsets.GetU16(&baseOffset) < 5)
if (strOffsets.getU16(&baseOffset) < 5)
return;

// Skip padding.
Expand Down Expand Up @@ -409,7 +416,16 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
SetRangesBase(form_value.Unsigned());
break;
case DW_AT_str_offsets_base:
// When we have a DW_AT_str_offsets_base attribute, it points us to the
// first string offset for this DWARFUnit which is after the string
// offsets table header. In this case we use the DWARF32/DWARF64 of the
// DWARFUnit to determine the string offset byte size. DWO files do not
// use this attribute and they point to the start of the string offsets
// table header which can be used to determine the DWARF32/DWARF64 status
// of the string table. See SetDwoStrOffsetsBase() for now it figures out
// the m_str_offset_size value that should be used.
SetStrOffsetsBase(form_value.Unsigned());
m_str_offset_size = m_header.getDwarfOffsetByteSize();
break;
case DW_AT_low_pc:
SetBaseAddress(form_value.Address());
Expand Down Expand Up @@ -1079,10 +1095,9 @@ uint32_t DWARFUnit::GetHeaderByteSize() const { return m_header.getSize(); }

std::optional<uint64_t>
DWARFUnit::GetStringOffsetSectionItem(uint32_t index) const {
lldb::offset_t offset =
GetStrOffsetsBase() + index * m_header.getDwarfOffsetByteSize();
lldb::offset_t offset = GetStrOffsetsBase() + index * m_str_offset_size;
return m_dwarf.GetDWARFContext().getOrLoadStrOffsetsData().GetMaxU64(
&offset, m_header.getDwarfOffsetByteSize());
&offset, m_str_offset_size);
}

llvm::Expected<llvm::DWARFAddressRangesVector>
Expand Down
Loading
Loading