Stateful variable-location annotations in Disassembler::PrintInstructions() (follow-up to #147460) (#152887)
**Context** Follow-up to [#147460](https://github.com/llvm/llvm-project/pull/147460), which added the ability to surface register-resident variable locations. This PR moves the annotation logic out of `Instruction::Dump()` and into `Disassembler::PrintInstructions()`, and adds lightweight state tracking so we only print changes at range starts and when variables go out of scope. --- ## What this does While iterating the instructions for a function, we maintain a “live variable map” keyed by `lldb::user_id_t` (the `Variable`’s ID) to remember each variable’s last emitted location string. For each instruction: - **New (or newly visible) variable** → print `name = <location>` once at the start of its DWARF location range, cache it. - **Location changed** (e.g., DWARF range switched to a different register/const) → print the updated mapping. - **Out of scope** (was tracked previously but not found for the current PC) → print `name = <undef>` and drop it. This produces **concise, stateful annotations** that highlight variable lifetime transitions without spamming every line. --- ## Why in `PrintInstructions()`? - Keeps `Instruction` stateless and avoids changing the `Instruction::Dump()` virtual API. - Makes it straightforward to diff state across instructions (`prev → current`) inside the single driver loop. --- ## How it works (high-level) 1. For the current PC, get in-scope variables via `StackFrame::GetInScopeVariableList(/*get_parent=*/true)`. 2. For each `Variable`, query `DWARFExpressionList::GetExpressionEntryAtAddress(func_load_addr, current_pc)` (added in #144238). 3. If the entry exists, call `DumpLocation(..., eDescriptionLevelBrief, abi)` to get a short, ABI-aware location string (e.g., `DW_OP_reg3 RBX → RBX`). 4. Compare against the last emitted location in the live map: - If not present → emit `name = <location>` and record it. - If different → emit updated mapping and record it. 5. After processing current in-scope variables, compute the set difference vs. the previous map and emit `name = <undef>` for any that disappeared. Internally: - We respect file↔load address translation already provided by `DWARFExpressionList`. - We reuse the ABI to map LLVM register numbers to arch register names. --- ## Example output (x86_64, simplified) ``` -> 0x55c6f5f6a140 <+0>: cmpl $0x2, %edi ; argc = RDI, argv = RSI 0x55c6f5f6a143 <+3>: jl 0x55c6f5f6a176 ; <+54> at d_original_example.c:6:3 0x55c6f5f6a145 <+5>: pushq %r15 0x55c6f5f6a147 <+7>: pushq %r14 0x55c6f5f6a149 <+9>: pushq %rbx 0x55c6f5f6a14a <+10>: movq %rsi, %rbx 0x55c6f5f6a14d <+13>: movl %edi, %r14d 0x55c6f5f6a150 <+16>: movl $0x1, %r15d ; argc = R14 0x55c6f5f6a156 <+22>: nopw %cs:(%rax,%rax) ; i = R15, argv = RBX 0x55c6f5f6a160 <+32>: movq (%rbx,%r15,8), %rdi 0x55c6f5f6a164 <+36>: callq 0x55c6f5f6a030 ; symbol stub for: puts 0x55c6f5f6a169 <+41>: incq %r15 0x55c6f5f6a16c <+44>: cmpq %r15, %r14 0x55c6f5f6a16f <+47>: jne 0x55c6f5f6a160 ; <+32> at d_original_example.c:5:10 0x55c6f5f6a171 <+49>: popq %rbx ; i = <undef> 0x55c6f5f6a172 <+50>: popq %r14 ; argv = RSI 0x55c6f5f6a174 <+52>: popq %r15 ; argc = RDI 0x55c6f5f6a176 <+54>: xorl %eax, %eax 0x55c6f5f6a178 <+56>: retq ``` Only transitions are shown: the start of a location, changes, and end-of-lifetime. --- ## Scope & limitations (by design) - Handles **simple locations** first (registers, const-in-register cases surfaced by `DumpLocation`). - **Memory/composite locations** are out of scope for this PR. - Annotations appear **only at range boundaries** (start/change/end) to minimize noise. - Output is **target-independent**; register names come from the target ABI. ## Implementation notes - All annotation printing now happens in `Disassembler::PrintInstructions()`. - Uses `std::unordered_map<lldb::user_id_t, std::string>` as the live map. - No persistent state across calls; the map is rebuilt while walking instruction by instruction. - **No changes** to the `Instruction` interface. --- ## Requested feedback - Placement and wording of the `<undef>` marker. - Whether we should optionally gate this behind a setting (currently always on when disassembling with an `ExecutionContext`). - Preference for immediate inclusion of tests vs. follow-up patch. --- Thanks for reviewing! Happy to adjust behavior/format based on feedback. --------- Co-authored-by: Jonas Devlieghere <jonas@devlieghere.com> Co-authored-by: Adrian Prantl <adrian.prantl@gmail.com>
This commit is contained in:
parent
6f2840dfeb
commit
8ec4db5e17
@ -169,7 +169,7 @@ public:
|
||||
|
||||
virtual bool IsAuthenticated() = 0;
|
||||
|
||||
bool CanSetBreakpoint ();
|
||||
bool CanSetBreakpoint();
|
||||
|
||||
virtual size_t Decode(const Disassembler &disassembler,
|
||||
const DataExtractor &data,
|
||||
@ -282,7 +282,7 @@ std::function<bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm);
|
||||
|
||||
std::function<bool(const Instruction::Operand &)>
|
||||
MatchOpType(Instruction::Operand::Type type);
|
||||
}
|
||||
} // namespace OperandMatchers
|
||||
|
||||
class InstructionList {
|
||||
public:
|
||||
@ -316,20 +316,19 @@ public:
|
||||
/// @param[in] ignore_calls
|
||||
/// It true, then fine the first branch instruction that isn't
|
||||
/// a function call (a branch that calls and returns to the next
|
||||
/// instruction). If false, find the instruction index of any
|
||||
/// instruction). If false, find the instruction index of any
|
||||
/// branch in the list.
|
||||
///
|
||||
///
|
||||
/// @param[out] found_calls
|
||||
/// If non-null, this will be set to true if any calls were found in
|
||||
/// If non-null, this will be set to true if any calls were found in
|
||||
/// extending the range.
|
||||
///
|
||||
///
|
||||
/// @return
|
||||
/// The instruction index of the first branch that is at or past
|
||||
/// \a start. Returns UINT32_MAX if no matching branches are
|
||||
/// \a start. Returns UINT32_MAX if no matching branches are
|
||||
/// found.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t GetIndexOfNextBranchInstruction(uint32_t start,
|
||||
bool ignore_calls,
|
||||
uint32_t GetIndexOfNextBranchInstruction(uint32_t start, bool ignore_calls,
|
||||
bool *found_calls) const;
|
||||
|
||||
uint32_t GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr,
|
||||
@ -399,6 +398,7 @@ public:
|
||||
eOptionMarkPCAddress =
|
||||
(1u << 3), // Mark the disassembly line the contains the PC
|
||||
eOptionShowControlFlowKind = (1u << 4),
|
||||
eOptionVariableAnnotations = (1u << 5),
|
||||
};
|
||||
|
||||
enum HexImmediateStyle {
|
||||
|
||||
@ -159,7 +159,8 @@ public:
|
||||
return data.GetByteSize() > 0;
|
||||
}
|
||||
|
||||
void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi) const;
|
||||
void DumpLocation(Stream *s, lldb::DescriptionLevel level, ABI *abi,
|
||||
llvm::DIDumpOptions options = {}) const;
|
||||
|
||||
bool MatchesOperand(StackFrame &frame, const Instruction::Operand &op) const;
|
||||
|
||||
|
||||
@ -154,6 +154,10 @@ Status CommandObjectDisassemble::CommandOptions::SetOptionValue(
|
||||
}
|
||||
} break;
|
||||
|
||||
case 'v':
|
||||
enable_variable_annotations = true;
|
||||
break;
|
||||
|
||||
case '\x01':
|
||||
force = true;
|
||||
break;
|
||||
@ -180,6 +184,7 @@ void CommandObjectDisassemble::CommandOptions::OptionParsingStarting(
|
||||
end_addr = LLDB_INVALID_ADDRESS;
|
||||
symbol_containing_addr = LLDB_INVALID_ADDRESS;
|
||||
raw = false;
|
||||
enable_variable_annotations = false;
|
||||
plugin_name.clear();
|
||||
|
||||
Target *target =
|
||||
@ -529,6 +534,9 @@ void CommandObjectDisassemble::DoExecute(Args &command,
|
||||
if (m_options.raw)
|
||||
options |= Disassembler::eOptionRawOuput;
|
||||
|
||||
if (m_options.enable_variable_annotations)
|
||||
options |= Disassembler::eOptionVariableAnnotations;
|
||||
|
||||
llvm::Expected<std::vector<AddressRange>> ranges =
|
||||
GetRangesForSelectedMode(result);
|
||||
if (!ranges) {
|
||||
|
||||
@ -78,6 +78,7 @@ public:
|
||||
// in SetOptionValue if anything the selects a location is set.
|
||||
lldb::addr_t symbol_containing_addr = 0;
|
||||
bool force = false;
|
||||
bool enable_variable_annotations = false;
|
||||
};
|
||||
|
||||
CommandObjectDisassemble(CommandInterpreter &interpreter);
|
||||
|
||||
@ -366,6 +366,8 @@ let Command = "disassemble" in {
|
||||
Desc<"Disassemble function containing this address.">;
|
||||
def disassemble_options_force : Option<"force", "\\x01">, Groups<[2,3,4,5,7]>,
|
||||
Desc<"Force disassembly of large functions.">;
|
||||
def disassemble_options_variable : Option<"variable", "v">,
|
||||
Desc<"Enable variable disassembly annotations for this invocation.">;
|
||||
}
|
||||
|
||||
let Command = "diagnostics dump" in {
|
||||
|
||||
@ -26,7 +26,11 @@
|
||||
#include "lldb/Symbol/Function.h"
|
||||
#include "lldb/Symbol/Symbol.h"
|
||||
#include "lldb/Symbol/SymbolContext.h"
|
||||
#include "lldb/Symbol/Variable.h"
|
||||
#include "lldb/Symbol/VariableList.h"
|
||||
#include "lldb/Target/ABI.h"
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/SectionLoadList.h"
|
||||
#include "lldb/Target/StackFrame.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
@ -41,6 +45,8 @@
|
||||
#include "lldb/lldb-private-enumerations.h"
|
||||
#include "lldb/lldb-private-interfaces.h"
|
||||
#include "lldb/lldb-private-types.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/TargetParser/Triple.h"
|
||||
|
||||
@ -376,6 +382,147 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch,
|
||||
}
|
||||
}
|
||||
|
||||
// Add variable location annotations to the disassembly output.
|
||||
//
|
||||
// For each instruction, this block attempts to resolve in-scope variables
|
||||
// and determine if the current PC falls within their
|
||||
// DWARF location entry. If so, it prints a simplified annotation using the
|
||||
// variable name and its resolved location (e.g., "var = reg; " ).
|
||||
//
|
||||
// Annotations are only included if the variable has a valid DWARF location
|
||||
// entry, and the location string is non-empty after filtering. Decoding
|
||||
// errors and DWARF opcodes are intentionally omitted to keep the output
|
||||
// concise and user-friendly.
|
||||
//
|
||||
// The goal is to give users helpful live variable hints alongside the
|
||||
// disassembled instruction stream, similar to how debug information
|
||||
// enhances source-level debugging.
|
||||
|
||||
struct VarState {
|
||||
std::string name; ///< Display name.
|
||||
std::string last_loc; ///< Last printed location (empty means <undef>).
|
||||
bool seen_this_inst = false;
|
||||
};
|
||||
|
||||
// Track live variables across instructions.
|
||||
llvm::DenseMap<lldb::user_id_t, VarState> live_vars;
|
||||
|
||||
// Stateful annotator: updates live_vars and returns only what should be
|
||||
// printed for THIS instruction.
|
||||
auto annotate_static = [&](Instruction &inst, Target &target,
|
||||
ModuleSP module_sp) -> std::vector<std::string> {
|
||||
std::vector<std::string> events;
|
||||
|
||||
// Reset per-instruction seen flags.
|
||||
for (auto &kv : live_vars)
|
||||
kv.second.seen_this_inst = false;
|
||||
|
||||
const Address &iaddr = inst.GetAddress();
|
||||
if (!module_sp) {
|
||||
// Everything previously live becomes <undef>.
|
||||
for (auto I = live_vars.begin(), E = live_vars.end(); I != E;) {
|
||||
auto Cur = I++;
|
||||
events.push_back(
|
||||
llvm::formatv("{0} = <undef>", Cur->second.name).str());
|
||||
live_vars.erase(Cur);
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
// Resolve innermost block at this *file* address.
|
||||
SymbolContext sc;
|
||||
const lldb::SymbolContextItem mask =
|
||||
eSymbolContextFunction | eSymbolContextBlock;
|
||||
if (!module_sp->ResolveSymbolContextForAddress(iaddr, mask, sc) ||
|
||||
!sc.function) {
|
||||
// No function context: everything dies here.
|
||||
for (auto I = live_vars.begin(), E = live_vars.end(); I != E;) {
|
||||
auto Cur = I++;
|
||||
events.push_back(
|
||||
llvm::formatv("{0} = <undef>", Cur->second.name).str());
|
||||
live_vars.erase(Cur);
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
Block *B = sc.block; ///< Innermost block containing iaddr.
|
||||
VariableList var_list;
|
||||
if (B) {
|
||||
auto filter = [](Variable *v) -> bool { return v && !v->IsArtificial(); };
|
||||
|
||||
B->AppendVariables(/*can_create*/ true,
|
||||
/*get_parent_variables*/ true,
|
||||
/*stop_if_block_is_inlined_function*/ false,
|
||||
/*filter*/ filter,
|
||||
/*variable_list*/ &var_list);
|
||||
}
|
||||
|
||||
const lldb::addr_t pc_file = iaddr.GetFileAddress();
|
||||
const lldb::addr_t func_file = sc.function->GetAddress().GetFileAddress();
|
||||
|
||||
// ABI from Target (pretty reg names if plugin exists). Safe to be null.
|
||||
lldb::ProcessSP no_process;
|
||||
lldb::ABISP abi_sp = ABI::FindPlugin(no_process, target.GetArchitecture());
|
||||
ABI *abi = abi_sp.get();
|
||||
|
||||
llvm::DIDumpOptions opts;
|
||||
opts.ShowAddresses = false;
|
||||
if (abi)
|
||||
opts.PrintRegisterOnly = true;
|
||||
|
||||
for (size_t i = 0, e = var_list.GetSize(); i != e; ++i) {
|
||||
lldb::VariableSP v = var_list.GetVariableAtIndex(i);
|
||||
if (!v || v->IsArtificial())
|
||||
continue;
|
||||
|
||||
const char *nm = v->GetName().AsCString();
|
||||
llvm::StringRef name = nm ? nm : "<anon>";
|
||||
|
||||
lldb_private::DWARFExpressionList &exprs = v->LocationExpressionList();
|
||||
if (!exprs.IsValid())
|
||||
continue;
|
||||
|
||||
auto entry_or_err = exprs.GetExpressionEntryAtAddress(func_file, pc_file);
|
||||
if (!entry_or_err)
|
||||
continue;
|
||||
|
||||
auto entry = *entry_or_err;
|
||||
|
||||
StreamString loc_ss;
|
||||
entry.expr->DumpLocation(&loc_ss, eDescriptionLevelBrief, abi, opts);
|
||||
llvm::StringRef loc = llvm::StringRef(loc_ss.GetString()).trim();
|
||||
if (loc.empty())
|
||||
continue;
|
||||
|
||||
auto ins = live_vars.insert(
|
||||
{v->GetID(), VarState{name.str(), loc.str(), /*seen*/ true}});
|
||||
if (ins.second) {
|
||||
// Newly live.
|
||||
events.push_back(llvm::formatv("{0} = {1}", name, loc).str());
|
||||
} else {
|
||||
VarState &vs = ins.first->second;
|
||||
vs.seen_this_inst = true;
|
||||
if (vs.last_loc != loc) {
|
||||
vs.last_loc = loc.str();
|
||||
events.push_back(llvm::formatv("{0} = {1}", vs.name, loc).str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Anything previously live that we didn't see a location for at this inst
|
||||
// is now <undef>.
|
||||
for (auto I = live_vars.begin(), E = live_vars.end(); I != E;) {
|
||||
auto Cur = I++;
|
||||
if (!Cur->second.seen_this_inst) {
|
||||
events.push_back(
|
||||
llvm::formatv("{0} = <undef>", Cur->second.name).str());
|
||||
live_vars.erase(Cur);
|
||||
}
|
||||
}
|
||||
|
||||
return events;
|
||||
};
|
||||
|
||||
previous_symbol = nullptr;
|
||||
SourceLine previous_line;
|
||||
for (size_t i = 0; i < num_instructions_found; ++i) {
|
||||
@ -540,10 +687,26 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch,
|
||||
const bool show_bytes = (options & eOptionShowBytes) != 0;
|
||||
const bool show_control_flow_kind =
|
||||
(options & eOptionShowControlFlowKind) != 0;
|
||||
inst->Dump(&strm, max_opcode_byte_size, true, show_bytes,
|
||||
|
||||
StreamString inst_line;
|
||||
|
||||
inst->Dump(&inst_line, max_opcode_byte_size, true, show_bytes,
|
||||
show_control_flow_kind, &exe_ctx, &sc, &prev_sc, nullptr,
|
||||
address_text_size);
|
||||
|
||||
if ((options & eOptionVariableAnnotations) && target_sp) {
|
||||
auto annotations = annotate_static(*inst, *target_sp, module_sp);
|
||||
if (!annotations.empty()) {
|
||||
const size_t annotation_column = 100;
|
||||
inst_line.FillLastLineToColumn(annotation_column, ' ');
|
||||
inst_line.PutCString("; ");
|
||||
inst_line.PutCString(llvm::join(annotations, ", "));
|
||||
}
|
||||
}
|
||||
|
||||
strm.PutCString(inst_line.GetString());
|
||||
strm.EOL();
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -724,9 +887,7 @@ bool Instruction::DumpEmulation(const ArchSpec &arch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Instruction::CanSetBreakpoint () {
|
||||
return !HasDelaySlot();
|
||||
}
|
||||
bool Instruction::CanSetBreakpoint() { return !HasDelaySlot(); }
|
||||
|
||||
bool Instruction::HasDelaySlot() {
|
||||
// Default is false.
|
||||
@ -1073,10 +1234,8 @@ void InstructionList::Append(lldb::InstructionSP &inst_sp) {
|
||||
m_instructions.push_back(inst_sp);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
InstructionList::GetIndexOfNextBranchInstruction(uint32_t start,
|
||||
bool ignore_calls,
|
||||
bool *found_calls) const {
|
||||
uint32_t InstructionList::GetIndexOfNextBranchInstruction(
|
||||
uint32_t start, bool ignore_calls, bool *found_calls) const {
|
||||
size_t num_instructions = m_instructions.size();
|
||||
|
||||
uint32_t next_branch = UINT32_MAX;
|
||||
|
||||
@ -67,7 +67,8 @@ void DWARFExpression::UpdateValue(uint64_t const_value,
|
||||
}
|
||||
|
||||
void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
|
||||
ABI *abi) const {
|
||||
ABI *abi,
|
||||
llvm::DIDumpOptions options) const {
|
||||
auto *MCRegInfo = abi ? &abi->GetMCRegisterInfo() : nullptr;
|
||||
auto GetRegName = [&MCRegInfo](uint64_t DwarfRegNum,
|
||||
bool IsEH) -> llvm::StringRef {
|
||||
@ -79,10 +80,9 @@ void DWARFExpression::DumpLocation(Stream *s, lldb::DescriptionLevel level,
|
||||
return llvm::StringRef(RegName);
|
||||
return {};
|
||||
};
|
||||
llvm::DIDumpOptions DumpOpts;
|
||||
DumpOpts.GetNameForDWARFReg = GetRegName;
|
||||
options.GetNameForDWARFReg = GetRegName;
|
||||
llvm::DWARFExpression E(m_data.GetAsLLVM(), m_data.GetAddressByteSize());
|
||||
llvm::printDwarfExpression(&E, s->AsRawOstream(), DumpOpts, nullptr);
|
||||
llvm::printDwarfExpression(&E, s->AsRawOstream(), options, nullptr);
|
||||
}
|
||||
|
||||
RegisterKind DWARFExpression::GetRegisterKind() const { return m_reg_kind; }
|
||||
|
||||
@ -266,6 +266,7 @@ bool StackFrame::ChangePC(addr_t pc) {
|
||||
|
||||
const char *StackFrame::Disassemble() {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
||||
|
||||
if (!m_disassembly.Empty())
|
||||
return m_disassembly.GetData();
|
||||
|
||||
@ -440,10 +441,10 @@ VariableList *StackFrame::GetVariableList(bool get_file_globals,
|
||||
const bool get_child_variables = true;
|
||||
const bool can_create = true;
|
||||
const bool stop_if_child_block_is_inlined_function = true;
|
||||
frame_block->AppendBlockVariables(can_create, get_child_variables,
|
||||
stop_if_child_block_is_inlined_function,
|
||||
[](Variable *v) { return true; },
|
||||
m_variable_list_sp.get());
|
||||
frame_block->AppendBlockVariables(
|
||||
can_create, get_child_variables,
|
||||
stop_if_child_block_is_inlined_function,
|
||||
[](Variable *v) { return true; }, m_variable_list_sp.get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1227,10 +1228,12 @@ StackFrame::GetValueObjectForFrameVariable(const VariableSP &variable_sp,
|
||||
VariableList *var_list = GetVariableList(true, nullptr);
|
||||
if (var_list) {
|
||||
// Make sure the variable is a frame variable
|
||||
const uint32_t var_idx = var_list->FindIndexForVariable(variable_sp.get());
|
||||
const uint32_t var_idx =
|
||||
var_list->FindIndexForVariable(variable_sp.get());
|
||||
const uint32_t num_variables = var_list->GetSize();
|
||||
if (var_idx < num_variables) {
|
||||
valobj_sp = m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
|
||||
valobj_sp =
|
||||
m_variable_list_value_objects.GetValueObjectAtIndex(var_idx);
|
||||
if (!valobj_sp) {
|
||||
if (m_variable_list_value_objects.GetSize() < num_variables)
|
||||
m_variable_list_value_objects.Resize(num_variables);
|
||||
@ -1764,11 +1767,9 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
|
||||
|
||||
if (clobbered_reg_matcher(operands[0])) {
|
||||
origin_operand = &operands[1];
|
||||
}
|
||||
else if (clobbered_reg_matcher(operands[1])) {
|
||||
} else if (clobbered_reg_matcher(operands[1])) {
|
||||
origin_operand = &operands[0];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1794,8 +1795,7 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
|
||||
if (!source_path) {
|
||||
continue;
|
||||
}
|
||||
source_path =
|
||||
GetValueForDereferincingOffset(frame, source_path, offset);
|
||||
source_path = GetValueForDereferincingOffset(frame, source_path, offset);
|
||||
}
|
||||
|
||||
if (source_path) {
|
||||
@ -1805,7 +1805,7 @@ lldb::ValueObjectSP DoGuessValueAt(StackFrame &frame, ConstString reg,
|
||||
|
||||
return ValueObjectSP();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg,
|
||||
int64_t offset) {
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
# List all assembler inputs stable test fixtures.
|
||||
ASM_SOURCES := \
|
||||
d_original_example.s \
|
||||
regs_int_params.s \
|
||||
regs_fp_params.s \
|
||||
regs_mixed_params.s \
|
||||
live_across_call.s \
|
||||
loop_reg_rotate.s \
|
||||
seed_reg_const_undef.s
|
||||
|
||||
ASM_OBJS := $(ASM_SOURCES:.s=.o)
|
||||
|
||||
# Provide a tiny dummy so the harness can link an exe without ASM_OBJS.
|
||||
C_SOURCES := dummy_main.c
|
||||
|
||||
# Generating the dummy source on demand.
|
||||
dummy_main.c:
|
||||
@echo 'int main(void){return 0;}' > $@
|
||||
|
||||
# Assemble .s → .o using the configured compiler.
|
||||
%.o: %.s
|
||||
$(CC) -c -x assembler $< -o $@
|
||||
|
||||
# Default target: build all .o fixtures and the dummy exe.
|
||||
.PHONY: all
|
||||
all: $(ASM_OBJS) $(EXE)
|
||||
|
||||
# Keeping things tidy.
|
||||
clean::
|
||||
$(RM) -f $(ASM_OBJS) dummy_main.c
|
||||
|
||||
include Makefile.rules
|
||||
@ -0,0 +1,108 @@
|
||||
from lldbsuite.test.lldbtest import *
|
||||
from lldbsuite.test.decorators import *
|
||||
import lldb
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
class TestVariableAnnotationsDisassembler(TestBase):
|
||||
def _build_obj(self, obj_name: str) -> str:
|
||||
# Let the Makefile build all .o’s (pattern rule). Then grab the one we need.
|
||||
self.build()
|
||||
obj = self.getBuildArtifact(obj_name)
|
||||
self.assertTrue(os.path.exists(obj), f"missing object: {obj}")
|
||||
return obj
|
||||
|
||||
def _create_target(self, path):
|
||||
target = self.dbg.CreateTarget(path)
|
||||
self.assertTrue(target, f"failed to create target for {path}")
|
||||
return target
|
||||
|
||||
def _disassemble_verbose_symbol(self, symname):
|
||||
self.runCmd(f"disassemble -n {symname} -v", check=True)
|
||||
return self.res.GetOutput()
|
||||
|
||||
def test_d_original_example_O1(self):
|
||||
obj = self._build_obj("d_original_example.o")
|
||||
target = self._create_target(obj)
|
||||
out = self._disassemble_verbose_symbol("main")
|
||||
print(out)
|
||||
self.assertIn("argc = ", out)
|
||||
self.assertIn("argv = ", out)
|
||||
self.assertIn("i = ", out)
|
||||
self.assertNotIn("<decoding error>", out)
|
||||
|
||||
@no_debug_info_test
|
||||
def test_regs_int_params(self):
|
||||
obj = self._build_obj("regs_int_params.o")
|
||||
target = self._create_target(obj)
|
||||
out = self._disassemble_verbose_symbol("regs_int_params")
|
||||
print(out)
|
||||
self.assertRegex(out, r"\ba\s*=\s*(DW_OP_reg5\b|RDI\b)")
|
||||
self.assertRegex(out, r"\bb\s*=\s*(DW_OP_reg4\b|RSI\b)")
|
||||
self.assertRegex(out, r"\bc\s*=\s*(DW_OP_reg1\b|RDX\b)")
|
||||
self.assertRegex(out, r"\bd\s*=\s*(DW_OP_reg2\b|RCX\b)")
|
||||
self.assertRegex(out, r"\be\s*=\s*(DW_OP_reg8\b|R8\b)")
|
||||
self.assertRegex(out, r"\bf\s*=\s*(DW_OP_reg9\b|R9\b)")
|
||||
self.assertNotIn("<decoding error>", out)
|
||||
|
||||
@no_debug_info_test
|
||||
def test_regs_fp_params(self):
|
||||
obj = self._build_obj("regs_fp_params.o")
|
||||
target = self._create_target(obj)
|
||||
out = self._disassemble_verbose_symbol("regs_fp_params")
|
||||
print(out)
|
||||
self.assertRegex(out, r"\ba\s*=\s*(DW_OP_reg17\b|XMM0\b)")
|
||||
self.assertRegex(out, r"\bb\s*=\s*(DW_OP_reg18\b|XMM1\b)")
|
||||
self.assertRegex(out, r"\bc\s*=\s*(DW_OP_reg19\b|XMM2\b)")
|
||||
self.assertRegex(out, r"\bd\s*=\s*(DW_OP_reg20\b|XMM3\b)")
|
||||
self.assertRegex(out, r"\be\s*=\s*(DW_OP_reg21\b|XMM4\b)")
|
||||
self.assertRegex(out, r"\bf\s*=\s*(DW_OP_reg22\b|XMM5\b)")
|
||||
self.assertNotIn("<decoding error>", out)
|
||||
|
||||
@no_debug_info_test
|
||||
def test_regs_mixed_params(self):
|
||||
obj = self._build_obj("regs_mixed_params.o")
|
||||
target = self._create_target(obj)
|
||||
out = self._disassemble_verbose_symbol("regs_mixed_params")
|
||||
print(out)
|
||||
self.assertRegex(out, r"\ba\s*=\s*(DW_OP_reg5\b|RDI\b)")
|
||||
self.assertRegex(out, r"\bb\s*=\s*(DW_OP_reg4\b|RSI\b)")
|
||||
self.assertRegex(out, r"\bx\s*=\s*(DW_OP_reg17\b|XMM0\b|DW_OP_reg\d+\b)")
|
||||
self.assertRegex(out, r"\by\s*=\s*(DW_OP_reg18\b|XMM1\b|DW_OP_reg\d+\b)")
|
||||
self.assertRegex(out, r"\bc\s*=\s*(DW_OP_reg1\b|RDX\b)")
|
||||
self.assertRegex(out, r"\bz\s*=\s*(DW_OP_reg19\b|XMM2\b|DW_OP_reg\d+\b)")
|
||||
self.assertNotIn("<decoding error>", out)
|
||||
|
||||
@no_debug_info_test
|
||||
def test_live_across_call(self):
|
||||
obj = self._build_obj("live_across_call.o")
|
||||
target = self._create_target(obj)
|
||||
out = self._disassemble_verbose_symbol("live_across_call")
|
||||
print(out)
|
||||
self.assertRegex(out, r"\bx\s*=\s*(DW_OP_reg5\b|RDI\b)")
|
||||
self.assertIn("call", out)
|
||||
self.assertRegex(out, r"\br\s*=\s*(DW_OP_reg0\b|RAX\b|DW_OP_reg\d+\b)")
|
||||
self.assertNotIn("<decoding error>", out)
|
||||
|
||||
@no_debug_info_test
|
||||
def test_loop_reg_rotate(self):
|
||||
obj = self._build_obj("loop_reg_rotate.o")
|
||||
target = self._create_target(obj)
|
||||
out = self._disassemble_verbose_symbol("loop_reg_rotate")
|
||||
print(out)
|
||||
self.assertRegex(out, r"\bn\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)")
|
||||
self.assertRegex(out, r"\bseed\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)")
|
||||
self.assertRegex(out, r"\bk\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)")
|
||||
self.assertRegex(out, r"\bj\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)")
|
||||
self.assertRegex(out, r"\bi\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)")
|
||||
self.assertNotIn("<decoding error>", out)
|
||||
|
||||
@no_debug_info_test
|
||||
def test_seed_reg_const_undef(self):
|
||||
obj = self._build_obj("seed_reg_const_undef.o")
|
||||
target = self._create_target(obj)
|
||||
out = self._disassemble_verbose_symbol("main")
|
||||
print(out)
|
||||
self.assertRegex(out, r"\b(i|argc)\s*=\s*(DW_OP_reg\d+\b|R[A-Z0-9]+)")
|
||||
self.assertNotIn("<decoding error>", out)
|
||||
@ -0,0 +1,461 @@
|
||||
/* Original C (for context):
|
||||
* #include <stdio.h>
|
||||
*
|
||||
* int main(int argc, char **argv) {
|
||||
* for (int i = 1; i < argc; ++i)
|
||||
* puts(argv[i]);
|
||||
* return 0;
|
||||
* }
|
||||
*/
|
||||
.file "d_original_example.c"
|
||||
.text
|
||||
.globl main # -- Begin function main
|
||||
.p2align 4
|
||||
.type main,@function
|
||||
main: # @main
|
||||
.Lfunc_begin0:
|
||||
.file 0 "." "d_original_example.c" md5 0x25192a1d5a6018cf37d369f9004fab00
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: main:argc <- $edi
|
||||
#DEBUG_VALUE: main:argv <- $rsi
|
||||
#DEBUG_VALUE: i <- 1
|
||||
.loc 0 4 21 prologue_end # d_original_example.c:4:21
|
||||
cmpl $2, %edi
|
||||
.Ltmp0:
|
||||
.loc 0 4 3 is_stmt 0 # d_original_example.c:4:3
|
||||
jl .LBB0_4
|
||||
.Ltmp1:
|
||||
# %bb.1: # %for.body.preheader
|
||||
#DEBUG_VALUE: main:argc <- $edi
|
||||
#DEBUG_VALUE: main:argv <- $rsi
|
||||
#DEBUG_VALUE: i <- 1
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
pushq %r15
|
||||
pushq %r14
|
||||
pushq %rbx
|
||||
pushq %rax
|
||||
.cfi_offset %rbx, -40
|
||||
.cfi_offset %r14, -32
|
||||
.cfi_offset %r15, -24
|
||||
movq %rsi, %rbx
|
||||
.Ltmp2:
|
||||
.loc 0 4 21 # d_original_example.c:4:21
|
||||
movl %edi, %r14d
|
||||
.Ltmp3:
|
||||
#DEBUG_VALUE: main:argc <- $r14d
|
||||
.loc 0 0 21 # d_original_example.c:0:21
|
||||
movl $1, %r15d
|
||||
.Ltmp4:
|
||||
.p2align 4
|
||||
.LBB0_2: # %for.body
|
||||
# =>This Inner Loop Header: Depth=1
|
||||
#DEBUG_VALUE: main:argc <- $r14d
|
||||
#DEBUG_VALUE: main:argv <- $rbx
|
||||
#DEBUG_VALUE: i <- $r15
|
||||
.loc 0 5 10 is_stmt 1 # d_original_example.c:5:10
|
||||
movq (%rbx,%r15,8), %rdi
|
||||
.loc 0 5 5 is_stmt 0 # d_original_example.c:5:5
|
||||
callq puts@PLT
|
||||
.Ltmp5:
|
||||
.loc 0 4 29 is_stmt 1 # d_original_example.c:4:29
|
||||
incq %r15
|
||||
.Ltmp6:
|
||||
#DEBUG_VALUE: i <- $r15
|
||||
.loc 0 4 21 is_stmt 0 # d_original_example.c:4:21
|
||||
cmpq %r15, %r14
|
||||
.Ltmp7:
|
||||
.loc 0 4 3 # d_original_example.c:4:3
|
||||
jne .LBB0_2
|
||||
.Ltmp8:
|
||||
# %bb.3:
|
||||
#DEBUG_VALUE: main:argc <- $r14d
|
||||
#DEBUG_VALUE: main:argv <- $rbx
|
||||
#DEBUG_VALUE: i <- $r15
|
||||
.loc 0 0 3 # d_original_example.c:0:3
|
||||
addq $8, %rsp
|
||||
popq %rbx
|
||||
.Ltmp9:
|
||||
#DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
|
||||
popq %r14
|
||||
.Ltmp10:
|
||||
#DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
|
||||
popq %r15
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
.cfi_restore %rbx
|
||||
.cfi_restore %r14
|
||||
.cfi_restore %r15
|
||||
.cfi_restore %rbp
|
||||
.Ltmp11:
|
||||
.LBB0_4: # %for.cond.cleanup
|
||||
#DEBUG_VALUE: main:argc <- [DW_OP_LLVM_entry_value 1] $edi
|
||||
#DEBUG_VALUE: main:argv <- [DW_OP_LLVM_entry_value 1] $rsi
|
||||
.loc 0 6 3 is_stmt 1 # d_original_example.c:6:3
|
||||
xorl %eax, %eax
|
||||
retq
|
||||
.Ltmp12:
|
||||
.Lfunc_end0:
|
||||
.size main, .Lfunc_end0-main
|
||||
.cfi_endproc
|
||||
.file 1 "/usr/include" "stdio.h" md5 0xf31eefcc3f15835fc5a4023a625cf609
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 3 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.long .Ldebug_loc1-.Lloclists_table_base0
|
||||
.long .Ldebug_loc2-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp3-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp3-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp10-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 94 # super-register DW_OP_reg14
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp10-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc1:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 84 # DW_OP_reg4
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 83 # DW_OP_reg3
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 84 # DW_OP_reg4
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc2:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
|
||||
.byte 3 # Loc expr size
|
||||
.byte 17 # DW_OP_consts
|
||||
.byte 1 # 1
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp8-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 95 # DW_OP_reg15
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_end0:
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 114 # DW_AT_str_offsets_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 16 # DW_AT_stmt_list
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 27 # DW_AT_comp_dir
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.ascii "\214\001" # DW_AT_loclists_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 39 # DW_AT_prototyped
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 11 # DW_TAG_lexical_block
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 6 # Abbreviation Code
|
||||
.byte 72 # DW_TAG_call_site
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 127 # DW_AT_call_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 125 # DW_AT_call_return_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 7 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 39 # DW_AT_prototyped
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 60 # DW_AT_declaration
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 8 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 9 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 10 # Abbreviation Code
|
||||
.byte 15 # DW_TAG_pointer_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 11 # Abbreviation Code
|
||||
.byte 38 # DW_TAG_const_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x7f DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 29 # DW_AT_language
|
||||
.byte 1 # DW_AT_name
|
||||
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||
.byte 2 # DW_AT_comp_dir
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0x38 DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
# DW_AT_call_all_calls
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 3 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 110 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x36:0x9 DW_TAG_formal_parameter
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 3 # DW_AT_decl_line
|
||||
.long 110 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0x3f:0x9 DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 3 # DW_AT_decl_line
|
||||
.long 128 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x48:0x10 DW_TAG_lexical_block
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Ltmp8-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 5 # Abbrev [5] 0x4e:0x9 DW_TAG_variable
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 9 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 4 # DW_AT_decl_line
|
||||
.long 110 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 6 # Abbrev [6] 0x58:0x6 DW_TAG_call_site
|
||||
.long 95 # DW_AT_call_origin
|
||||
.byte 1 # DW_AT_call_return_pc
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 7 # Abbrev [7] 0x5f:0xf DW_TAG_subprogram
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 1 # DW_AT_decl_file
|
||||
.short 661 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 110 # DW_AT_type
|
||||
# DW_AT_declaration
|
||||
# DW_AT_external
|
||||
.byte 8 # Abbrev [8] 0x68:0x5 DW_TAG_formal_parameter
|
||||
.long 114 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 9 # Abbrev [9] 0x6e:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 10 # Abbrev [10] 0x72:0x5 DW_TAG_pointer_type
|
||||
.long 119 # DW_AT_type
|
||||
.byte 11 # Abbrev [11] 0x77:0x5 DW_TAG_const_type
|
||||
.long 124 # DW_AT_type
|
||||
.byte 9 # Abbrev [9] 0x7c:0x4 DW_TAG_base_type
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 6 # DW_AT_encoding
|
||||
.byte 1 # DW_AT_byte_size
|
||||
.byte 10 # Abbrev [10] 0x80:0x5 DW_TAG_pointer_type
|
||||
.long 133 # DW_AT_type
|
||||
.byte 10 # Abbrev [10] 0x85:0x5 DW_TAG_pointer_type
|
||||
.long 124 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 44 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "d_original_example.c" # string offset=119
|
||||
.Linfo_string2:
|
||||
.asciz "." # string offset=140
|
||||
.Linfo_string3:
|
||||
.asciz "puts" # string offset=142
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=147
|
||||
.Linfo_string5:
|
||||
.asciz "char" # string offset=151
|
||||
.Linfo_string6:
|
||||
.asciz "main" # string offset=156
|
||||
.Linfo_string7:
|
||||
.asciz "argc" # string offset=161
|
||||
.Linfo_string8:
|
||||
.asciz "argv" # string offset=166
|
||||
.Linfo_string9:
|
||||
.asciz "i" # string offset=171
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.long .Linfo_string9
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.quad .Ltmp5
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
||||
@ -0,0 +1,371 @@
|
||||
/* Original C (for context):
|
||||
* // Declare a real external call so the compiler must respect ABI clobbers.
|
||||
* extern int leaf(int) __attribute__((noinline));
|
||||
*
|
||||
* __attribute__((noinline))
|
||||
* int live_across_call(int x) {
|
||||
* volatile int a = x; // a starts in a GPR (from arg)
|
||||
* asm volatile("" :: "r"(a)); // keep 'a' live in a register
|
||||
* int r = leaf(a); // 'a' is live across the call
|
||||
* asm volatile("" :: "r"(a), "r"(r));// still live afterwards
|
||||
* return a + r;
|
||||
* }
|
||||
*/
|
||||
.file "live_across_call.c"
|
||||
.text
|
||||
.globl live_across_call # -- Begin function live_across_call
|
||||
.p2align 4
|
||||
.type live_across_call,@function
|
||||
live_across_call: # @live_across_call
|
||||
.Lfunc_begin0:
|
||||
.file 0 "." "live_across_call.c" md5 0x351c37295026edf0d468774d35f47e5e
|
||||
.loc 0 5 0 # live_across_call.c:5:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: live_across_call:x <- $edi
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
subq $16, %rsp
|
||||
.Ltmp0:
|
||||
.loc 0 6 16 prologue_end # live_across_call.c:6:16
|
||||
movl %edi, -4(%rbp)
|
||||
.loc 0 7 26 # live_across_call.c:7:26
|
||||
movl -4(%rbp), %eax
|
||||
.loc 0 7 3 is_stmt 0 # live_across_call.c:7:3
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 8 16 is_stmt 1 # live_across_call.c:8:16
|
||||
movl -4(%rbp), %edi
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: live_across_call:x <- [DW_OP_LLVM_entry_value 1] $edi
|
||||
.loc 0 8 11 is_stmt 0 # live_across_call.c:8:11
|
||||
callq leaf@PLT
|
||||
.Ltmp2:
|
||||
#DEBUG_VALUE: live_across_call:r <- $eax
|
||||
.loc 0 9 26 is_stmt 1 # live_across_call.c:9:26
|
||||
movl -4(%rbp), %ecx
|
||||
.loc 0 9 3 is_stmt 0 # live_across_call.c:9:3
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 10 12 is_stmt 1 # live_across_call.c:10:12
|
||||
addl -4(%rbp), %eax
|
||||
.Ltmp3:
|
||||
.loc 0 10 3 epilogue_begin is_stmt 0 # live_across_call.c:10:3
|
||||
addq $16, %rsp
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
retq
|
||||
.Ltmp4:
|
||||
.Lfunc_end0:
|
||||
.size live_across_call, .Lfunc_end0-live_across_call
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 2 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.long .Ldebug_loc1-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc1:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp2-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp3-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 80 # super-register DW_OP_reg0
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_end0:
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 114 # DW_AT_str_offsets_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 16 # DW_AT_stmt_list
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 27 # DW_AT_comp_dir
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.ascii "\214\001" # DW_AT_loclists_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 39 # DW_AT_prototyped
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 6 # Abbreviation Code
|
||||
.byte 72 # DW_TAG_call_site
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 127 # DW_AT_call_origin
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 125 # DW_AT_call_return_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 7 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 39 # DW_AT_prototyped
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 60 # DW_AT_declaration
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 8 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 9 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 10 # Abbreviation Code
|
||||
.byte 53 # DW_TAG_volatile_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x66 DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 29 # DW_AT_language
|
||||
.byte 1 # DW_AT_name
|
||||
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||
.byte 2 # DW_AT_comp_dir
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0x33 DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
# DW_AT_call_all_calls
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 5 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 104 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x36:0x9 DW_TAG_formal_parameter
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 5 # DW_AT_decl_line
|
||||
.long 104 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x3f:0xb DW_TAG_variable
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 145
|
||||
.byte 124
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 6 # DW_AT_decl_line
|
||||
.long 108 # DW_AT_type
|
||||
.byte 5 # Abbrev [5] 0x4a:0x9 DW_TAG_variable
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 8 # DW_AT_decl_line
|
||||
.long 104 # DW_AT_type
|
||||
.byte 6 # Abbrev [6] 0x53:0x6 DW_TAG_call_site
|
||||
.long 90 # DW_AT_call_origin
|
||||
.byte 1 # DW_AT_call_return_pc
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 7 # Abbrev [7] 0x5a:0xe DW_TAG_subprogram
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 104 # DW_AT_type
|
||||
# DW_AT_declaration
|
||||
# DW_AT_external
|
||||
.byte 8 # Abbrev [8] 0x62:0x5 DW_TAG_formal_parameter
|
||||
.long 104 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 9 # Abbrev [9] 0x68:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 10 # Abbrev [10] 0x6c:0x5 DW_TAG_volatile_type
|
||||
.long 104 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 40 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "live_across_call.c" # string offset=119
|
||||
.Linfo_string2:
|
||||
.asciz "." # string offset=138
|
||||
.Linfo_string3:
|
||||
.asciz "leaf" # string offset=140
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=145
|
||||
.Linfo_string5:
|
||||
.asciz "live_across_call" # string offset=149
|
||||
.Linfo_string6:
|
||||
.asciz "a" # string offset=166
|
||||
.Linfo_string7:
|
||||
.asciz "x" # string offset=168
|
||||
.Linfo_string8:
|
||||
.asciz "r" # string offset=170
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.quad .Ltmp2
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
||||
@ -0,0 +1,557 @@
|
||||
/* Original C (for context):
|
||||
* __attribute__((noinline))
|
||||
* int loop_reg_rotate(int n, int seed) {
|
||||
* volatile int acc = seed; // keep as a named local
|
||||
* int i = 0, j = 1, k = 2; // extra pressure but not enough to spill
|
||||
*
|
||||
* for (int t = 0; t < n; ++t) {
|
||||
* // Mix uses so the allocator may reshuffle regs for 'acc'
|
||||
* acc = acc + i;
|
||||
* asm volatile("" :: "r"(acc)); // pin 'acc' live here
|
||||
* acc = acc ^ j;
|
||||
* asm volatile("" :: "r"(acc)); // and here
|
||||
* acc = acc + k;
|
||||
* i ^= acc; j += acc; k ^= j;
|
||||
* }
|
||||
*
|
||||
* asm volatile("" :: "r"(acc));
|
||||
* return acc + i + j + k;
|
||||
* }
|
||||
*/
|
||||
.file "loop_reg_rotate.c"
|
||||
.text
|
||||
.globl loop_reg_rotate # -- Begin function loop_reg_rotate
|
||||
.p2align 4
|
||||
.type loop_reg_rotate,@function
|
||||
loop_reg_rotate: # @loop_reg_rotate
|
||||
.Lfunc_begin0:
|
||||
.file 0 "." "loop_reg_rotate.c" md5 0x388f52de76e9442230e689fb9be1b4ef
|
||||
.loc 0 2 0 # loop_reg_rotate.c:2:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: loop_reg_rotate:n <- $edi
|
||||
#DEBUG_VALUE: loop_reg_rotate:seed <- $esi
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
.Ltmp0:
|
||||
.loc 0 3 16 prologue_end # loop_reg_rotate.c:3:16
|
||||
movl %esi, -4(%rbp)
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: loop_reg_rotate:i <- 0
|
||||
#DEBUG_VALUE: loop_reg_rotate:j <- 1
|
||||
#DEBUG_VALUE: loop_reg_rotate:k <- 2
|
||||
#DEBUG_VALUE: t <- 0
|
||||
.loc 0 6 21 # loop_reg_rotate.c:6:21
|
||||
testl %edi, %edi
|
||||
.Ltmp2:
|
||||
.loc 0 6 3 is_stmt 0 # loop_reg_rotate.c:6:3
|
||||
jle .LBB0_1
|
||||
.Ltmp3:
|
||||
# %bb.3: # %for.body.preheader
|
||||
#DEBUG_VALUE: loop_reg_rotate:n <- $edi
|
||||
#DEBUG_VALUE: loop_reg_rotate:seed <- $esi
|
||||
#DEBUG_VALUE: loop_reg_rotate:i <- 0
|
||||
#DEBUG_VALUE: loop_reg_rotate:j <- 1
|
||||
#DEBUG_VALUE: loop_reg_rotate:k <- 2
|
||||
#DEBUG_VALUE: t <- 0
|
||||
.loc 0 0 3 # loop_reg_rotate.c:0:3
|
||||
xorl %eax, %eax
|
||||
movl $1, %edx
|
||||
movl $2, %ecx
|
||||
.Ltmp4:
|
||||
.p2align 4
|
||||
.LBB0_4: # %for.body
|
||||
# =>This Inner Loop Header: Depth=1
|
||||
#DEBUG_VALUE: loop_reg_rotate:n <- [DW_OP_LLVM_entry_value 1] $edi
|
||||
#DEBUG_VALUE: loop_reg_rotate:seed <- [DW_OP_LLVM_entry_value 1] $esi
|
||||
#DEBUG_VALUE: t <- [DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_minus, DW_OP_consts 18446744073709551615, DW_OP_div, DW_OP_stack_value] undef, undef
|
||||
#DEBUG_VALUE: loop_reg_rotate:k <- $ecx
|
||||
#DEBUG_VALUE: loop_reg_rotate:j <- $edx
|
||||
#DEBUG_VALUE: loop_reg_rotate:i <- $eax
|
||||
.loc 0 8 9 is_stmt 1 # loop_reg_rotate.c:8:9
|
||||
addl %eax, -4(%rbp)
|
||||
.loc 0 9 28 # loop_reg_rotate.c:9:28
|
||||
movl -4(%rbp), %esi
|
||||
.loc 0 9 5 is_stmt 0 # loop_reg_rotate.c:9:5
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 10 9 is_stmt 1 # loop_reg_rotate.c:10:9
|
||||
xorl %edx, -4(%rbp)
|
||||
.loc 0 11 28 # loop_reg_rotate.c:11:28
|
||||
movl -4(%rbp), %esi
|
||||
.loc 0 11 5 is_stmt 0 # loop_reg_rotate.c:11:5
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 12 9 is_stmt 1 # loop_reg_rotate.c:12:9
|
||||
addl %ecx, -4(%rbp)
|
||||
.loc 0 13 7 # loop_reg_rotate.c:13:7
|
||||
xorl -4(%rbp), %eax
|
||||
.Ltmp5:
|
||||
#DEBUG_VALUE: loop_reg_rotate:i <- $eax
|
||||
.loc 0 13 17 is_stmt 0 # loop_reg_rotate.c:13:17
|
||||
addl -4(%rbp), %edx
|
||||
.Ltmp6:
|
||||
#DEBUG_VALUE: loop_reg_rotate:j <- $edx
|
||||
.loc 0 13 27 # loop_reg_rotate.c:13:27
|
||||
xorl %edx, %ecx
|
||||
.Ltmp7:
|
||||
#DEBUG_VALUE: loop_reg_rotate:k <- $ecx
|
||||
#DEBUG_VALUE: t <- [DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_minus, DW_OP_consts 18446744073709551615, DW_OP_div, DW_OP_consts 1, DW_OP_plus, DW_OP_stack_value] undef, undef
|
||||
.loc 0 6 21 is_stmt 1 # loop_reg_rotate.c:6:21
|
||||
decl %edi
|
||||
.Ltmp8:
|
||||
.loc 0 6 3 is_stmt 0 # loop_reg_rotate.c:6:3
|
||||
jne .LBB0_4
|
||||
jmp .LBB0_2
|
||||
.Ltmp9:
|
||||
.LBB0_1:
|
||||
#DEBUG_VALUE: loop_reg_rotate:n <- $edi
|
||||
#DEBUG_VALUE: loop_reg_rotate:seed <- $esi
|
||||
#DEBUG_VALUE: loop_reg_rotate:i <- 0
|
||||
#DEBUG_VALUE: loop_reg_rotate:j <- 1
|
||||
#DEBUG_VALUE: loop_reg_rotate:k <- 2
|
||||
#DEBUG_VALUE: t <- 0
|
||||
.loc 0 0 3 # loop_reg_rotate.c:0:3
|
||||
movl $2, %ecx
|
||||
movl $1, %edx
|
||||
xorl %eax, %eax
|
||||
.Ltmp10:
|
||||
.LBB0_2: # %for.cond.cleanup
|
||||
#DEBUG_VALUE: loop_reg_rotate:n <- [DW_OP_LLVM_entry_value 1] $edi
|
||||
#DEBUG_VALUE: loop_reg_rotate:seed <- [DW_OP_LLVM_entry_value 1] $esi
|
||||
.loc 0 16 26 is_stmt 1 # loop_reg_rotate.c:16:26
|
||||
movl -4(%rbp), %esi
|
||||
.loc 0 16 3 is_stmt 0 # loop_reg_rotate.c:16:3
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 17 14 is_stmt 1 # loop_reg_rotate.c:17:14
|
||||
addl %edx, %eax
|
||||
.loc 0 17 18 is_stmt 0 # loop_reg_rotate.c:17:18
|
||||
addl %ecx, %eax
|
||||
.loc 0 17 22 # loop_reg_rotate.c:17:22
|
||||
addl -4(%rbp), %eax
|
||||
.loc 0 17 3 epilogue_begin # loop_reg_rotate.c:17:3
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
retq
|
||||
.Ltmp11:
|
||||
.Lfunc_end0:
|
||||
.size loop_reg_rotate, .Lfunc_end0-loop_reg_rotate
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 6 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.long .Ldebug_loc1-.Lloclists_table_base0
|
||||
.long .Ldebug_loc2-.Lloclists_table_base0
|
||||
.long .Ldebug_loc3-.Lloclists_table_base0
|
||||
.long .Ldebug_loc4-.Lloclists_table_base0
|
||||
.long .Ldebug_loc5-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp10-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp10-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc1:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp10-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp10-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc2:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
|
||||
.byte 3 # Loc expr size
|
||||
.byte 17 # DW_OP_consts
|
||||
.byte 0 # 0
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 80 # super-register DW_OP_reg0
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp10-.Lfunc_begin0 # ending offset
|
||||
.byte 3 # Loc expr size
|
||||
.byte 17 # DW_OP_consts
|
||||
.byte 0 # 0
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc3:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
|
||||
.byte 3 # Loc expr size
|
||||
.byte 17 # DW_OP_consts
|
||||
.byte 1 # 1
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 81 # super-register DW_OP_reg1
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp10-.Lfunc_begin0 # ending offset
|
||||
.byte 3 # Loc expr size
|
||||
.byte 17 # DW_OP_consts
|
||||
.byte 1 # 1
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc4:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
|
||||
.byte 3 # Loc expr size
|
||||
.byte 17 # DW_OP_consts
|
||||
.byte 2 # 2
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 82 # super-register DW_OP_reg2
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp9-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp10-.Lfunc_begin0 # ending offset
|
||||
.byte 3 # Loc expr size
|
||||
.byte 17 # DW_OP_consts
|
||||
.byte 2 # 2
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc5:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp4-.Lfunc_begin0 # ending offset
|
||||
.byte 3 # Loc expr size
|
||||
.byte 17 # DW_OP_consts
|
||||
.byte 0 # 0
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_end0:
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 114 # DW_AT_str_offsets_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 16 # DW_AT_stmt_list
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 27 # DW_AT_comp_dir
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.ascii "\214\001" # DW_AT_loclists_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 39 # DW_AT_prototyped
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 6 # Abbreviation Code
|
||||
.byte 11 # DW_TAG_lexical_block
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 7 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 8 # Abbreviation Code
|
||||
.byte 53 # DW_TAG_volatile_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x7d DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 29 # DW_AT_language
|
||||
.byte 1 # DW_AT_name
|
||||
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||
.byte 2 # DW_AT_comp_dir
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0x58 DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
# DW_AT_call_all_calls
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 127 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x36:0x9 DW_TAG_formal_parameter
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 127 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0x3f:0x9 DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 127 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x48:0xb DW_TAG_variable
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 145
|
||||
.byte 124
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 3 # DW_AT_decl_line
|
||||
.long 131 # DW_AT_type
|
||||
.byte 5 # Abbrev [5] 0x53:0x9 DW_TAG_variable
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 4 # DW_AT_decl_line
|
||||
.long 127 # DW_AT_type
|
||||
.byte 5 # Abbrev [5] 0x5c:0x9 DW_TAG_variable
|
||||
.byte 3 # DW_AT_location
|
||||
.byte 9 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 4 # DW_AT_decl_line
|
||||
.long 127 # DW_AT_type
|
||||
.byte 5 # Abbrev [5] 0x65:0x9 DW_TAG_variable
|
||||
.byte 4 # DW_AT_location
|
||||
.byte 10 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 4 # DW_AT_decl_line
|
||||
.long 127 # DW_AT_type
|
||||
.byte 6 # Abbrev [6] 0x6e:0x10 DW_TAG_lexical_block
|
||||
.byte 1 # DW_AT_low_pc
|
||||
.long .Ltmp9-.Ltmp1 # DW_AT_high_pc
|
||||
.byte 5 # Abbrev [5] 0x74:0x9 DW_TAG_variable
|
||||
.byte 5 # DW_AT_location
|
||||
.byte 11 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 6 # DW_AT_decl_line
|
||||
.long 127 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 7 # Abbrev [7] 0x7f:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 8 # Abbrev [8] 0x83:0x5 DW_TAG_volatile_type
|
||||
.long 127 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 52 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "loop_reg_rotate.c" # string offset=119
|
||||
.Linfo_string2:
|
||||
.asciz "." # string offset=137
|
||||
.Linfo_string3:
|
||||
.asciz "loop_reg_rotate" # string offset=139
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=155
|
||||
.Linfo_string5:
|
||||
.asciz "acc" # string offset=159
|
||||
.Linfo_string6:
|
||||
.asciz "n" # string offset=163
|
||||
.Linfo_string7:
|
||||
.asciz "seed" # string offset=165
|
||||
.Linfo_string8:
|
||||
.asciz "i" # string offset=170
|
||||
.Linfo_string9:
|
||||
.asciz "j" # string offset=172
|
||||
.Linfo_string10:
|
||||
.asciz "k" # string offset=174
|
||||
.Linfo_string11:
|
||||
.asciz "t" # string offset=176
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.long .Linfo_string9
|
||||
.long .Linfo_string10
|
||||
.long .Linfo_string11
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.quad .Ltmp1
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
||||
@ -0,0 +1,304 @@
|
||||
/* Original C (for context):
|
||||
* __attribute__((noinline))
|
||||
* double regs_fp_params(double a, double b, double c, double d, double e, double f) {
|
||||
* asm volatile("" :: "x"(a), "x"(b), "x"(c), "x"(d), "x"(e), "x"(f));
|
||||
* return a + b + c + d + e + f;
|
||||
* }*/
|
||||
.file "regs_fp_params.c"
|
||||
.text
|
||||
.globl regs_fp_params # -- Begin function regs_fp_params
|
||||
.p2align 4
|
||||
.type regs_fp_params,@function
|
||||
regs_fp_params: # @regs_fp_params
|
||||
.Lfunc_begin0:
|
||||
.file 0 "." "regs_fp_params.c" md5 0xdd883927454b0ea1cdce7b3c16c6a643
|
||||
.loc 0 2 0 # regs_fp_params.c:2:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: regs_fp_params:a <- $xmm0
|
||||
#DEBUG_VALUE: regs_fp_params:b <- $xmm1
|
||||
#DEBUG_VALUE: regs_fp_params:c <- $xmm2
|
||||
#DEBUG_VALUE: regs_fp_params:d <- $xmm3
|
||||
#DEBUG_VALUE: regs_fp_params:e <- $xmm4
|
||||
#DEBUG_VALUE: regs_fp_params:f <- $xmm5
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
.Ltmp0:
|
||||
.loc 0 3 3 prologue_end # regs_fp_params.c:3:3
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 4 12 # regs_fp_params.c:4:12
|
||||
addsd %xmm1, %xmm0
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: regs_fp_params:a <- [DW_OP_LLVM_entry_value 1] $xmm0
|
||||
.loc 0 4 16 is_stmt 0 # regs_fp_params.c:4:16
|
||||
addsd %xmm2, %xmm0
|
||||
.loc 0 4 20 # regs_fp_params.c:4:20
|
||||
addsd %xmm3, %xmm0
|
||||
.loc 0 4 24 # regs_fp_params.c:4:24
|
||||
addsd %xmm4, %xmm0
|
||||
.loc 0 4 28 # regs_fp_params.c:4:28
|
||||
addsd %xmm5, %xmm0
|
||||
.loc 0 4 3 epilogue_begin # regs_fp_params.c:4:3
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
retq
|
||||
.Ltmp2:
|
||||
.Lfunc_end0:
|
||||
.size regs_fp_params, .Lfunc_end0-regs_fp_params
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 1 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 97 # DW_OP_reg17
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 97 # DW_OP_reg17
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_end0:
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 114 # DW_AT_str_offsets_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 16 # DW_AT_stmt_list
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 27 # DW_AT_comp_dir
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.ascii "\214\001" # DW_AT_loclists_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 39 # DW_AT_prototyped
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x6b DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 29 # DW_AT_language
|
||||
.byte 1 # DW_AT_name
|
||||
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||
.byte 2 # DW_AT_comp_dir
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0x4b DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
# DW_AT_call_all_calls
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 114 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x36:0x9 DW_TAG_formal_parameter
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x3f:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 98
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x49:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 99
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x53:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 100
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x5d:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 101
|
||||
.byte 9 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x67:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 102
|
||||
.byte 10 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 5 # Abbrev [5] 0x72:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 4 # DW_AT_encoding
|
||||
.byte 8 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 48 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "regs_fp_params.c" # string offset=119
|
||||
.Linfo_string2:
|
||||
.asciz "." # string offset=136
|
||||
.Linfo_string3:
|
||||
.asciz "regs_fp_params" # string offset=138
|
||||
.Linfo_string4:
|
||||
.asciz "double" # string offset=153
|
||||
.Linfo_string5:
|
||||
.asciz "a" # string offset=160
|
||||
.Linfo_string6:
|
||||
.asciz "b" # string offset=162
|
||||
.Linfo_string7:
|
||||
.asciz "c" # string offset=164
|
||||
.Linfo_string8:
|
||||
.asciz "d" # string offset=166
|
||||
.Linfo_string9:
|
||||
.asciz "e" # string offset=168
|
||||
.Linfo_string10:
|
||||
.asciz "f" # string offset=170
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.long .Linfo_string9
|
||||
.long .Linfo_string10
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
||||
@ -0,0 +1,312 @@
|
||||
/* Original C (for context):
|
||||
* __attribute__((noinline))
|
||||
* int regs_int_params(int a, int b, int c, int d, int e, int f) {
|
||||
* // Keep all params in regs; avoid spilling to the stack.
|
||||
* // The compiler will usually keep a..f in the 6 integer-arg regs.
|
||||
* asm volatile("" :: "r"(a), "r"(b), "r"(c), "r"(d), "r"(e), "r"(f));
|
||||
* return a + b + c + d + e + f;
|
||||
* }
|
||||
*/
|
||||
.file "regs_int_params.c"
|
||||
.text
|
||||
.globl regs_int_params # -- Begin function regs_int_params
|
||||
.p2align 4
|
||||
.type regs_int_params,@function
|
||||
regs_int_params: # @regs_int_params
|
||||
.Lfunc_begin0:
|
||||
.file 0 "." "regs_int_params.c" md5 0xcf39432098ab893043cc8b4606354bd2
|
||||
.loc 0 2 0 # regs_int_params.c:2:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: regs_int_params:a <- $edi
|
||||
#DEBUG_VALUE: regs_int_params:b <- $esi
|
||||
#DEBUG_VALUE: regs_int_params:c <- $edx
|
||||
#DEBUG_VALUE: regs_int_params:d <- $ecx
|
||||
#DEBUG_VALUE: regs_int_params:e <- $r8d
|
||||
#DEBUG_VALUE: regs_int_params:f <- $r9d
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
# kill: def $r9d killed $r9d def $r9
|
||||
# kill: def $r8d killed $r8d def $r8
|
||||
# kill: def $ecx killed $ecx def $rcx
|
||||
# kill: def $edx killed $edx def $rdx
|
||||
# kill: def $esi killed $esi def $rsi
|
||||
# kill: def $edi killed $edi def $rdi
|
||||
.Ltmp0:
|
||||
.loc 0 5 3 prologue_end # regs_int_params.c:5:3
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 6 12 # regs_int_params.c:6:12
|
||||
addl %edi, %esi
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: regs_int_params:b <- [DW_OP_LLVM_entry_value 1] $esi
|
||||
.loc 0 6 16 is_stmt 0 # regs_int_params.c:6:16
|
||||
leal (%rdx,%rcx), %eax
|
||||
.loc 0 6 20 # regs_int_params.c:6:20
|
||||
addl %esi, %eax
|
||||
.loc 0 6 28 # regs_int_params.c:6:28
|
||||
addl %r8d, %eax
|
||||
addl %r9d, %eax
|
||||
.loc 0 6 3 epilogue_begin # regs_int_params.c:6:3
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
retq
|
||||
.Ltmp2:
|
||||
.Lfunc_end0:
|
||||
.size regs_int_params, .Lfunc_end0-regs_int_params
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 1 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_end0:
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 114 # DW_AT_str_offsets_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 16 # DW_AT_stmt_list
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 27 # DW_AT_comp_dir
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.ascii "\214\001" # DW_AT_loclists_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 39 # DW_AT_prototyped
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x6b DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 29 # DW_AT_language
|
||||
.byte 1 # DW_AT_name
|
||||
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||
.byte 2 # DW_AT_comp_dir
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0x4b DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
# DW_AT_call_all_calls
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 114 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x36:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x40:0x9 DW_TAG_formal_parameter
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0x49:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 81
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0x53:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 82
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0x5d:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 88
|
||||
.byte 9 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0x67:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 89
|
||||
.byte 10 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 114 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 5 # Abbrev [5] 0x72:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 48 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "regs_int_params.c" # string offset=119
|
||||
.Linfo_string2:
|
||||
.asciz "." # string offset=137
|
||||
.Linfo_string3:
|
||||
.asciz "regs_int_params" # string offset=139
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=155
|
||||
.Linfo_string5:
|
||||
.asciz "a" # string offset=159
|
||||
.Linfo_string6:
|
||||
.asciz "b" # string offset=161
|
||||
.Linfo_string7:
|
||||
.asciz "c" # string offset=163
|
||||
.Linfo_string8:
|
||||
.asciz "d" # string offset=165
|
||||
.Linfo_string9:
|
||||
.asciz "e" # string offset=167
|
||||
.Linfo_string10:
|
||||
.asciz "f" # string offset=169
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.long .Linfo_string9
|
||||
.long .Linfo_string10
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
||||
@ -0,0 +1,375 @@
|
||||
/* Original C (for context):
|
||||
* __attribute__((noinline))
|
||||
* double regs_mixed_params(int a, int b, double x, double y, int c, double z) {
|
||||
* // Keep everything live; avoid spills.
|
||||
* asm volatile("" :: "r"(a), "r"(b), "x"(x), "x"(y), "r"(c), "x"(z));
|
||||
* // Some mixing so values stay in regs long enough to annotate.
|
||||
* double r = (double)(a + b + c) + x + y + z;
|
||||
* asm volatile("" :: "x"(r), "r"(a), "x"(x));
|
||||
* return r;
|
||||
* }
|
||||
*/
|
||||
.file "regs_mixed_params.c"
|
||||
.file 0 "." "regs_mixed_params.c" md5 0x73c4bda40238ae460aaecb3a6a2603cf
|
||||
.text
|
||||
.globl regs_mixed_params # -- Begin function regs_mixed_params
|
||||
.p2align 4
|
||||
.type regs_mixed_params,@function
|
||||
regs_mixed_params: # @regs_mixed_params
|
||||
.Lfunc_begin0:
|
||||
.loc 0 2 0 # regs_mixed_params.c:2:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: regs_mixed_params:a <- $edi
|
||||
#DEBUG_VALUE: regs_mixed_params:b <- $esi
|
||||
#DEBUG_VALUE: regs_mixed_params:x <- $xmm0
|
||||
#DEBUG_VALUE: regs_mixed_params:y <- $xmm1
|
||||
#DEBUG_VALUE: regs_mixed_params:c <- $edx
|
||||
#DEBUG_VALUE: regs_mixed_params:z <- $xmm2
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
.Ltmp0:
|
||||
.loc 0 4 3 prologue_end # regs_mixed_params.c:4:3
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 6 25 # regs_mixed_params.c:6:25
|
||||
addl %edi, %esi
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: regs_mixed_params:b <- [DW_OP_LLVM_entry_value 1] $esi
|
||||
.loc 0 6 29 is_stmt 0 # regs_mixed_params.c:6:29
|
||||
addl %edx, %esi
|
||||
.loc 0 6 14 # regs_mixed_params.c:6:14
|
||||
cvtsi2sd %esi, %xmm4
|
||||
.loc 0 6 34 # regs_mixed_params.c:6:34
|
||||
movapd %xmm0, %xmm3
|
||||
addsd %xmm4, %xmm3
|
||||
.loc 0 6 38 # regs_mixed_params.c:6:38
|
||||
addsd %xmm1, %xmm3
|
||||
.loc 0 6 42 # regs_mixed_params.c:6:42
|
||||
addsd %xmm2, %xmm3
|
||||
.Ltmp2:
|
||||
#DEBUG_VALUE: regs_mixed_params:r <- $xmm3
|
||||
.loc 0 7 3 is_stmt 1 # regs_mixed_params.c:7:3
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 8 3 # regs_mixed_params.c:8:3
|
||||
movapd %xmm3, %xmm0
|
||||
.Ltmp3:
|
||||
#DEBUG_VALUE: regs_mixed_params:x <- [DW_OP_LLVM_entry_value 1] $xmm0
|
||||
.loc 0 8 3 epilogue_begin is_stmt 0 # regs_mixed_params.c:8:3
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
retq
|
||||
.Ltmp4:
|
||||
.Lfunc_end0:
|
||||
.size regs_mixed_params, .Lfunc_end0-regs_mixed_params
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 3 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.long .Ldebug_loc1-.Lloclists_table_base0
|
||||
.long .Ldebug_loc2-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 84 # super-register DW_OP_reg4
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc1:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp3-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 97 # DW_OP_reg17
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp3-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 4 # Loc expr size
|
||||
.byte 163 # DW_OP_entry_value
|
||||
.byte 1 # 1
|
||||
.byte 97 # DW_OP_reg17
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_loc2:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp2-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 100 # DW_OP_reg20
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_end0:
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 114 # DW_AT_str_offsets_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 16 # DW_AT_stmt_list
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 27 # DW_AT_comp_dir
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.ascii "\214\001" # DW_AT_loclists_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 39 # DW_AT_prototyped
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 6 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x77 DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 29 # DW_AT_language
|
||||
.byte 1 # DW_AT_name
|
||||
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||
.byte 2 # DW_AT_comp_dir
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0x4 DW_TAG_base_type
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 4 # DW_AT_encoding
|
||||
.byte 8 # DW_AT_byte_size
|
||||
.byte 3 # Abbrev [3] 0x2b:0x53 DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
# DW_AT_call_all_calls
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 39 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 4 # Abbrev [4] 0x3a:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 126 # DW_AT_type
|
||||
.byte 5 # Abbrev [5] 0x44:0x9 DW_TAG_formal_parameter
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 126 # DW_AT_type
|
||||
.byte 5 # Abbrev [5] 0x4d:0x9 DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 39 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x56:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 98
|
||||
.byte 9 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 39 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x60:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 81
|
||||
.byte 10 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 126 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x6a:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 99
|
||||
.byte 11 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 2 # DW_AT_decl_line
|
||||
.long 39 # DW_AT_type
|
||||
.byte 6 # Abbrev [6] 0x74:0x9 DW_TAG_variable
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 12 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 6 # DW_AT_decl_line
|
||||
.long 39 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 2 # Abbrev [2] 0x7e:0x4 DW_TAG_base_type
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 56 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "regs_mixed_params.c" # string offset=119
|
||||
.Linfo_string2:
|
||||
.asciz "." # string offset=139
|
||||
.Linfo_string3:
|
||||
.asciz "double" # string offset=141
|
||||
.Linfo_string4:
|
||||
.asciz "regs_mixed_params" # string offset=148
|
||||
.Linfo_string5:
|
||||
.asciz "a" # string offset=166
|
||||
.Linfo_string6:
|
||||
.asciz "int" # string offset=168
|
||||
.Linfo_string7:
|
||||
.asciz "b" # string offset=172
|
||||
.Linfo_string8:
|
||||
.asciz "x" # string offset=174
|
||||
.Linfo_string9:
|
||||
.asciz "y" # string offset=176
|
||||
.Linfo_string10:
|
||||
.asciz "c" # string offset=178
|
||||
.Linfo_string11:
|
||||
.asciz "z" # string offset=180
|
||||
.Linfo_string12:
|
||||
.asciz "r" # string offset=182
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.long .Linfo_string9
|
||||
.long .Linfo_string10
|
||||
.long .Linfo_string11
|
||||
.long .Linfo_string12
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
||||
@ -0,0 +1,289 @@
|
||||
/* Original C (for context):
|
||||
* __attribute__((noinline))
|
||||
* int main(int argc, char **argv) {
|
||||
* int i = argc; // i in a reg (DW_OP_regN)
|
||||
* asm volatile("" :: "r"(i)); // keep i live here
|
||||
* i = 0; // i becomes const 0 (DW_OP_constu 0, stack_value)
|
||||
* asm volatile("" :: "r"(i)); // keep the const range materialized
|
||||
* return 0; // i ends -> <undef> after its range
|
||||
* }
|
||||
*/
|
||||
|
||||
.file "seed_reg_const_undef.c"
|
||||
.text
|
||||
.globl main # -- Begin function main
|
||||
.p2align 4
|
||||
.type main,@function
|
||||
main: # @main
|
||||
.Lfunc_begin0:
|
||||
.file 0 "." "seed_reg_const_undef.c" md5 0x5e8dbf089d1bd72d395da802210b3138
|
||||
.loc 0 3 0 # seed_reg_const_undef.c:3:0
|
||||
.cfi_startproc
|
||||
# %bb.0: # %entry
|
||||
#DEBUG_VALUE: main:argc <- $edi
|
||||
#DEBUG_VALUE: main:argv <- $rsi
|
||||
pushq %rbp
|
||||
.cfi_def_cfa_offset 16
|
||||
.cfi_offset %rbp, -16
|
||||
movq %rsp, %rbp
|
||||
.cfi_def_cfa_register %rbp
|
||||
.Ltmp0:
|
||||
#DEBUG_VALUE: main:i <- $edi
|
||||
.loc 0 5 3 prologue_end # seed_reg_const_undef.c:5:3
|
||||
#APP
|
||||
#NO_APP
|
||||
.Ltmp1:
|
||||
#DEBUG_VALUE: main:i <- 0
|
||||
.loc 0 7 3 # seed_reg_const_undef.c:7:3
|
||||
xorl %eax, %eax
|
||||
#APP
|
||||
#NO_APP
|
||||
.loc 0 8 3 # seed_reg_const_undef.c:8:3
|
||||
xorl %eax, %eax
|
||||
.loc 0 8 3 epilogue_begin is_stmt 0 # seed_reg_const_undef.c:8:3
|
||||
popq %rbp
|
||||
.cfi_def_cfa %rsp, 8
|
||||
retq
|
||||
.Ltmp2:
|
||||
.Lfunc_end0:
|
||||
.size main, .Lfunc_end0-main
|
||||
.cfi_endproc
|
||||
# -- End function
|
||||
.section .debug_loclists,"",@progbits
|
||||
.long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length
|
||||
.Ldebug_list_header_start0:
|
||||
.short 5 # Version
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.long 1 # Offset entry count
|
||||
.Lloclists_table_base0:
|
||||
.long .Ldebug_loc0-.Lloclists_table_base0
|
||||
.Ldebug_loc0:
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp0-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # ending offset
|
||||
.byte 1 # Loc expr size
|
||||
.byte 85 # super-register DW_OP_reg5
|
||||
.byte 4 # DW_LLE_offset_pair
|
||||
.uleb128 .Ltmp1-.Lfunc_begin0 # starting offset
|
||||
.uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset
|
||||
.byte 3 # Loc expr size
|
||||
.byte 17 # DW_OP_consts
|
||||
.byte 0 # 0
|
||||
.byte 159 # DW_OP_stack_value
|
||||
.byte 0 # DW_LLE_end_of_list
|
||||
.Ldebug_list_header_end0:
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 1 # Abbreviation Code
|
||||
.byte 17 # DW_TAG_compile_unit
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 37 # DW_AT_producer
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 19 # DW_AT_language
|
||||
.byte 5 # DW_FORM_data2
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 114 # DW_AT_str_offsets_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 16 # DW_AT_stmt_list
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 27 # DW_AT_comp_dir
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 115 # DW_AT_addr_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.ascii "\214\001" # DW_AT_loclists_base
|
||||
.byte 23 # DW_FORM_sec_offset
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 2 # Abbreviation Code
|
||||
.byte 46 # DW_TAG_subprogram
|
||||
.byte 1 # DW_CHILDREN_yes
|
||||
.byte 17 # DW_AT_low_pc
|
||||
.byte 27 # DW_FORM_addrx
|
||||
.byte 18 # DW_AT_high_pc
|
||||
.byte 6 # DW_FORM_data4
|
||||
.byte 64 # DW_AT_frame_base
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 122 # DW_AT_call_all_calls
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 39 # DW_AT_prototyped
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 63 # DW_AT_external
|
||||
.byte 25 # DW_FORM_flag_present
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 3 # Abbreviation Code
|
||||
.byte 5 # DW_TAG_formal_parameter
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 24 # DW_FORM_exprloc
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 4 # Abbreviation Code
|
||||
.byte 52 # DW_TAG_variable
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 2 # DW_AT_location
|
||||
.byte 34 # DW_FORM_loclistx
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 58 # DW_AT_decl_file
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 59 # DW_AT_decl_line
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 5 # Abbreviation Code
|
||||
.byte 36 # DW_TAG_base_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 37 # DW_FORM_strx1
|
||||
.byte 62 # DW_AT_encoding
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 11 # DW_AT_byte_size
|
||||
.byte 11 # DW_FORM_data1
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 6 # Abbreviation Code
|
||||
.byte 15 # DW_TAG_pointer_type
|
||||
.byte 0 # DW_CHILDREN_no
|
||||
.byte 73 # DW_AT_type
|
||||
.byte 19 # DW_FORM_ref4
|
||||
.byte 0 # EOM(1)
|
||||
.byte 0 # EOM(2)
|
||||
.byte 0 # EOM(3)
|
||||
.section .debug_info,"",@progbits
|
||||
.Lcu_begin0:
|
||||
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
|
||||
.Ldebug_info_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.byte 1 # Abbrev [1] 0xc:0x5b DW_TAG_compile_unit
|
||||
.byte 0 # DW_AT_producer
|
||||
.short 29 # DW_AT_language
|
||||
.byte 1 # DW_AT_name
|
||||
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
|
||||
.long .Lline_table_start0 # DW_AT_stmt_list
|
||||
.byte 2 # DW_AT_comp_dir
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.long .Laddr_table_base0 # DW_AT_addr_base
|
||||
.long .Lloclists_table_base0 # DW_AT_loclists_base
|
||||
.byte 2 # Abbrev [2] 0x27:0x2d DW_TAG_subprogram
|
||||
.byte 0 # DW_AT_low_pc
|
||||
.long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
|
||||
.byte 1 # DW_AT_frame_base
|
||||
.byte 86
|
||||
# DW_AT_call_all_calls
|
||||
.byte 3 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 3 # DW_AT_decl_line
|
||||
# DW_AT_prototyped
|
||||
.long 84 # DW_AT_type
|
||||
# DW_AT_external
|
||||
.byte 3 # Abbrev [3] 0x36:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 85
|
||||
.byte 5 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 3 # DW_AT_decl_line
|
||||
.long 84 # DW_AT_type
|
||||
.byte 3 # Abbrev [3] 0x40:0xa DW_TAG_formal_parameter
|
||||
.byte 1 # DW_AT_location
|
||||
.byte 84
|
||||
.byte 6 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 3 # DW_AT_decl_line
|
||||
.long 88 # DW_AT_type
|
||||
.byte 4 # Abbrev [4] 0x4a:0x9 DW_TAG_variable
|
||||
.byte 0 # DW_AT_location
|
||||
.byte 8 # DW_AT_name
|
||||
.byte 0 # DW_AT_decl_file
|
||||
.byte 4 # DW_AT_decl_line
|
||||
.long 84 # DW_AT_type
|
||||
.byte 0 # End Of Children Mark
|
||||
.byte 5 # Abbrev [5] 0x54:0x4 DW_TAG_base_type
|
||||
.byte 4 # DW_AT_name
|
||||
.byte 5 # DW_AT_encoding
|
||||
.byte 4 # DW_AT_byte_size
|
||||
.byte 6 # Abbrev [6] 0x58:0x5 DW_TAG_pointer_type
|
||||
.long 93 # DW_AT_type
|
||||
.byte 6 # Abbrev [6] 0x5d:0x5 DW_TAG_pointer_type
|
||||
.long 98 # DW_AT_type
|
||||
.byte 5 # Abbrev [5] 0x62:0x4 DW_TAG_base_type
|
||||
.byte 7 # DW_AT_name
|
||||
.byte 6 # DW_AT_encoding
|
||||
.byte 1 # DW_AT_byte_size
|
||||
.byte 0 # End Of Children Mark
|
||||
.Ldebug_info_end0:
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long 40 # Length of String Offsets Set
|
||||
.short 5
|
||||
.short 0
|
||||
.Lstr_offsets_base0:
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
.Linfo_string0:
|
||||
.asciz "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)" # string offset=0
|
||||
.Linfo_string1:
|
||||
.asciz "seed_reg_const_undef.c" # string offset=119
|
||||
.Linfo_string2:
|
||||
.asciz "." # string offset=142
|
||||
.Linfo_string3:
|
||||
.asciz "main" # string offset=144
|
||||
.Linfo_string4:
|
||||
.asciz "int" # string offset=149
|
||||
.Linfo_string5:
|
||||
.asciz "argc" # string offset=153
|
||||
.Linfo_string6:
|
||||
.asciz "argv" # string offset=158
|
||||
.Linfo_string7:
|
||||
.asciz "char" # string offset=163
|
||||
.Linfo_string8:
|
||||
.asciz "i" # string offset=168
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
.long .Linfo_string0
|
||||
.long .Linfo_string1
|
||||
.long .Linfo_string2
|
||||
.long .Linfo_string3
|
||||
.long .Linfo_string4
|
||||
.long .Linfo_string5
|
||||
.long .Linfo_string6
|
||||
.long .Linfo_string7
|
||||
.long .Linfo_string8
|
||||
.section .debug_addr,"",@progbits
|
||||
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
|
||||
.Ldebug_addr_start0:
|
||||
.short 5 # DWARF version number
|
||||
.byte 8 # Address size
|
||||
.byte 0 # Segment selector size
|
||||
.Laddr_table_base0:
|
||||
.quad .Lfunc_begin0
|
||||
.Ldebug_addr_end0:
|
||||
.ident "clang version 22.0.0git (https://github.com/UltimateForce21/llvm-project.git 79c0a9e1e7da0f727c41d27c9c6ff8a28bb7d06f)"
|
||||
.section ".note.GNU-stack","",@progbits
|
||||
.addrsig
|
||||
.section .debug_line,"",@progbits
|
||||
.Lline_table_start0:
|
||||
@ -209,6 +209,7 @@ struct DIDumpOptions {
|
||||
bool IsEH = false;
|
||||
bool DumpNonSkeleton = false;
|
||||
bool ShowAggregateErrors = false;
|
||||
bool PrintRegisterOnly = false;
|
||||
std::string JsonErrSummaryFile;
|
||||
std::function<llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)>
|
||||
GetNameForDWARFReg;
|
||||
|
||||
@ -48,13 +48,52 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
|
||||
DIDumpOptions DumpOpts, const DWARFExpression *Expr,
|
||||
DWARFUnit *U) {
|
||||
if (Op->isError()) {
|
||||
OS << "<decoding error>";
|
||||
if (!DumpOpts.PrintRegisterOnly)
|
||||
OS << "<decoding error>";
|
||||
return false;
|
||||
}
|
||||
|
||||
StringRef Name = OperationEncodingString(Op->getCode());
|
||||
assert(!Name.empty() && "DW_OP has no name!");
|
||||
OS << Name;
|
||||
// In "register-only" mode, still show simple constant-valued locations.
|
||||
// This lets clients print annotations like "i = 0" when the location is
|
||||
// a constant (e.g. DW_OP_constu/consts ... DW_OP_stack_value).
|
||||
// We continue to suppress all other non-register ops in this mode.
|
||||
if (DumpOpts.PrintRegisterOnly) {
|
||||
// First, try pretty-printing registers (existing behavior below also does
|
||||
// this, but we need to short-circuit here to avoid printing opcode names).
|
||||
if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
|
||||
(Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
|
||||
Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx ||
|
||||
Op->getCode() == DW_OP_regval_type) {
|
||||
if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(),
|
||||
Op->getRawOperands()))
|
||||
return true;
|
||||
// If we couldn't pretty-print, fall through and suppress.
|
||||
}
|
||||
|
||||
// Show constants (decimal), suppress everything else.
|
||||
if (Op->getCode() == DW_OP_constu) {
|
||||
OS << (uint64_t)Op->getRawOperand(0);
|
||||
return true;
|
||||
}
|
||||
if (Op->getCode() == DW_OP_consts) {
|
||||
OS << (int64_t)Op->getRawOperand(0);
|
||||
return true;
|
||||
}
|
||||
if (Op->getCode() >= DW_OP_lit0 && Op->getCode() <= DW_OP_lit31) {
|
||||
OS << (unsigned)(Op->getCode() - DW_OP_lit0);
|
||||
return true;
|
||||
}
|
||||
if (Op->getCode() == DW_OP_stack_value)
|
||||
return true; // metadata; don't print a token
|
||||
|
||||
return true; // suppress other opcodes silently in register-only mode
|
||||
}
|
||||
|
||||
if (!DumpOpts.PrintRegisterOnly) {
|
||||
StringRef Name = OperationEncodingString(Op->getCode());
|
||||
assert(!Name.empty() && "DW_OP has no name!");
|
||||
OS << Name;
|
||||
}
|
||||
|
||||
if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
|
||||
(Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
|
||||
@ -64,48 +103,51 @@ static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
|
||||
Op->getRawOperands()))
|
||||
return true;
|
||||
|
||||
for (unsigned Operand = 0; Operand < Op->getDescription().Op.size();
|
||||
++Operand) {
|
||||
unsigned Size = Op->getDescription().Op[Operand];
|
||||
unsigned Signed = Size & DWARFExpression::Operation::SignBit;
|
||||
if (!DumpOpts.PrintRegisterOnly) {
|
||||
for (unsigned Operand = 0; Operand < Op->getDescription().Op.size();
|
||||
++Operand) {
|
||||
unsigned Size = Op->getDescription().Op[Operand];
|
||||
unsigned Signed = Size & DWARFExpression::Operation::SignBit;
|
||||
|
||||
if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
|
||||
StringRef SubName =
|
||||
SubOperationEncodingString(Op->getCode(), Op->getRawOperand(Operand));
|
||||
assert(!SubName.empty() && "DW_OP SubOp has no name!");
|
||||
OS << " " << SubName;
|
||||
} else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
|
||||
// For DW_OP_convert the operand may be 0 to indicate that conversion to
|
||||
// the generic type should be done. The same holds for DW_OP_reinterpret,
|
||||
// which is currently not supported.
|
||||
if (Op->getCode() == DW_OP_convert && Op->getRawOperand(Operand) == 0)
|
||||
OS << " 0x0";
|
||||
else
|
||||
prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->getRawOperands(), Operand);
|
||||
} else if (Size == DWARFExpression::Operation::WasmLocationArg) {
|
||||
assert(Operand == 1);
|
||||
switch (Op->getRawOperand(0)) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: // global as uint32
|
||||
case 4:
|
||||
OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
|
||||
StringRef SubName = SubOperationEncodingString(
|
||||
Op->getCode(), Op->getRawOperand(Operand));
|
||||
assert(!SubName.empty() && "DW_OP SubOp has no name!");
|
||||
OS << " " << SubName;
|
||||
} else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
|
||||
// For DW_OP_convert the operand may be 0 to indicate that conversion to
|
||||
// the generic type should be done. The same holds for
|
||||
// DW_OP_reinterpret, which is currently not supported.
|
||||
if (Op->getCode() == DW_OP_convert && Op->getRawOperand(Operand) == 0)
|
||||
OS << " 0x0";
|
||||
else
|
||||
prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->getRawOperands(),
|
||||
Operand);
|
||||
} else if (Size == DWARFExpression::Operation::WasmLocationArg) {
|
||||
assert(Operand == 1);
|
||||
switch (Op->getRawOperand(0)) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: // global as uint32
|
||||
case 4:
|
||||
OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
} else if (Size == DWARFExpression::Operation::SizeBlock) {
|
||||
uint64_t Offset = Op->getRawOperand(Operand);
|
||||
for (unsigned i = 0; i < Op->getRawOperand(Operand - 1); ++i)
|
||||
OS << format(" 0x%02x",
|
||||
static_cast<uint8_t>(Expr->getData()[Offset++]));
|
||||
} else {
|
||||
if (Signed)
|
||||
OS << format(" %+" PRId64, (int64_t)Op->getRawOperand(Operand));
|
||||
else if (Op->getCode() != DW_OP_entry_value &&
|
||||
Op->getCode() != DW_OP_GNU_entry_value)
|
||||
OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
|
||||
}
|
||||
} else if (Size == DWARFExpression::Operation::SizeBlock) {
|
||||
uint64_t Offset = Op->getRawOperand(Operand);
|
||||
for (unsigned i = 0; i < Op->getRawOperand(Operand - 1); ++i)
|
||||
OS << format(" 0x%02x",
|
||||
static_cast<uint8_t>(Expr->getData()[Offset++]));
|
||||
} else {
|
||||
if (Signed)
|
||||
OS << format(" %+" PRId64, (int64_t)Op->getRawOperand(Operand));
|
||||
else if (Op->getCode() != DW_OP_entry_value &&
|
||||
Op->getCode() != DW_OP_GNU_entry_value)
|
||||
OS << format(" 0x%" PRIx64, Op->getRawOperand(Operand));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -120,29 +162,30 @@ void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
|
||||
|
||||
for (auto &Op : *E) {
|
||||
DumpOpts.IsEH = IsEH;
|
||||
if (!printOp(&Op, OS, DumpOpts, E, U)) {
|
||||
if (!printOp(&Op, OS, DumpOpts, E, U) && !DumpOpts.PrintRegisterOnly) {
|
||||
uint64_t FailOffset = Op.getEndOffset();
|
||||
while (FailOffset < E->getData().size())
|
||||
OS << format(" %02x", static_cast<uint8_t>(E->getData()[FailOffset++]));
|
||||
return;
|
||||
}
|
||||
if (!DumpOpts.PrintRegisterOnly) {
|
||||
if (Op.getCode() == DW_OP_entry_value ||
|
||||
Op.getCode() == DW_OP_GNU_entry_value) {
|
||||
OS << "(";
|
||||
EntryValExprSize = Op.getRawOperand(0);
|
||||
EntryValStartOffset = Op.getEndOffset();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Op.getCode() == DW_OP_entry_value ||
|
||||
Op.getCode() == DW_OP_GNU_entry_value) {
|
||||
OS << "(";
|
||||
EntryValExprSize = Op.getRawOperand(0);
|
||||
EntryValStartOffset = Op.getEndOffset();
|
||||
continue;
|
||||
if (EntryValExprSize) {
|
||||
EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
|
||||
if (EntryValExprSize == 0)
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
if (Op.getEndOffset() < E->getData().size())
|
||||
OS << ", ";
|
||||
}
|
||||
|
||||
if (EntryValExprSize) {
|
||||
EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
|
||||
if (EntryValExprSize == 0)
|
||||
OS << ")";
|
||||
}
|
||||
|
||||
if (Op.getEndOffset() < E->getData().size())
|
||||
OS << ", ";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user