This is regarding https://dwarfstd.org/issues/250924.2.html
In a meeting today Cary made an offhand comment along the lines of "Do
we need to add a remainder operator?" My initial thought was "no -- not
without a compelling justification". Then someone hypothesized that the
only reason DW_OP_mod even exists is to do address arithmetic. Thinking
about this a bit more, I'm left unconvinced that DWARF actually needs an
actual mathematical modulo operator but I can readily see that address
arithmetic could certainly use a remainder operation.
What do you guys think of this idea?
In DWARF6 we rename DW_OP_mod to DW_op_remainder leaving DW_OP_mod an
alias to DW_OP_remainder and then copy the semantics from the C
standard. Where:
# It is only defined for integral types.
# The C standard (since C99) specifies that the result of |a % b| has the
same sign as the dividend |a|.
# The relationship between division and remainder is given by the
equation: |(a / b) * b + (a % b) == a|.This holds true for both positive
and negative values.
# Integer division (|/|) in C performs truncation towards zero.
This way it can be easily implemented in consumers with the C "%"
operator. This would also make it backwardly compatible with any current
uses of DW_OP_mod for address arithmetic. Considering, Michael Eager's
pronouncement more than a decade ago that DW_OP_mod is only defined for
unsigned integral types, there should be no uses of the current
DW_OP_mod that incompatible with this interpretation.
If someone in the future does come up with a justification for a real
mathematical modulo operator then we can add that to the DWARF standard
giving it a name like DW_OP_modulo and then have a non-normative note
saying "that DW_OP_modulo should not be confused with the historic alias
for DW_OP_remainder DW_OP_mod."
This way we retain backward compatibility with the current
interpretation of DW_OP_mod where it is defined only for unsigned
integral types so that it can be used for address arithmetic without
having to dive into the complexity of the mathematical modulo operator.
In other words, this is the least work approach to resolving the issue.
If this sounds like an acceptable approach, then I will
rewrite 250924.2.html and forward it to Cary.
-ben
On 9/24/25 4:46 PM, Ron Brender wrote:
For starters, the proposed text is a non-starter (forgive the play on
words)
because there is no Chapter 2 Section 4 in Knuth's The Art of Computer
Programming Volume 1. Chapter 2 is entitled Information Structures, in
which
section 2.4 (is that what you mean by "Section 4"?) is entitled
Multilinked
Structures, and has nothing to do with the modulo operation.
The discussion mentions Section 1.2.4, which is actually in Volume 1,
Chapter 1, is entitled Integer Functions and Elementary Number Theory,
and does define and discuss the modulo operation.
Even if the citation were correct, I would object on the grounds that
I believe
the DWARF text should provide the definition, not a citation that the
reader
needs to consult. A footnote to an external source might be OK if
there were
complicated issues of possible supplementary interest.
Finally, the Knuth definition is given in terms of real numbers, of which
integers are a special case, using floor and ceiling operations. This
would be appropriate if DWARF DW_OP_mod were intended to apply
to floating-point operands but is rather pedantic overkill for just
integers.
But I think the real problem is not the definition of DW_OP_mod per se but
the definition of the generic type. DWARF Section 2.5.2 defines the
generic
type as an "integral type that has the size of an address on the
target machine
and unspecified signedness." We know that some architectures treat
addresses
as signed and some as unsigned integers, and DWARF is trying not to care.
Most of the time it mostly doesn't matter. But to be concrete, what
does one make of
DW_OP_lit5
DW_OP_lit2
DW_OP_neg
DW_OP_mod
If the generic type is signed, then the result is -1. However, if the
generic type
is thought to be unsigned, then "-2" is just a very large positive
number and
the result is 5.
We might think about solving this problem by defining the generic type
to be
a) signed
b) unsigned
c) signedness implementation-defined
I would not advocate either a) or b). Moreover, I would be very
caution in overturning the
"non-signedness" of generic type which has been characteristic of
DWARF from the beginning
(even before the name "generic type" was introduced).
Defining DW_OP_mod to be defined only for unsigned integers seems
overkill and unnecessary when no generic type operands are involved.
A more permissive approach is to specify that an operand of the generic
type is implicitly treated as unsigned. Then use the Knuth definition
restricted to
integers. This is close to Ben's second alternative but further
resolves the ambiguity
of generic signedness.
Ben has raised a definite problem for which further thought is surely
warranted...
Ron
On Wed, Sep 24, 2025 at 2:32 PM Ben Woodard via Dwarf-discuss
<dwarf-discuss@lists.dwarfstd.org> wrote:
Background:
Evidently, originally DWARF didn't allow arithmetic operations on
floating point numbers and most uses of the DWARF stack were done
with
the assumption that the values being acted upon were addresses and so
the computation was assumed to be acting upon unsigned numbers.
At some point, DWARF began to allow the arithmetic operations to
work on
floating point numbers and several operations were explicitly
defined to
work over non-integral values. This led to the paragraph in the
current
DWARF working draft that says in section 2.5.2.4 on page 37 lines
24-27:
"Operations other than DW_OP_abs, DW_OP_div, DW_OP_minus,
DW_OP_mul, DW_OP_neg and DW_OP_plus require integral types of the
operand (either integral base type or the generic type).
Operations do
not cause
an exception on overflow."
Unlike all the other arithmetic operations this explicitly limits
DW_OP_mod to integral base types and the generic type. It lumps
DW_OP_mod in with the logical operations. Furthermore, there are
multiple definitions of the modulo operator which vary in how they
handle signed values.
According to the dwarf-discuss archives, this issue came up back
in 2011
and at that time Michael Eager made a pronouncement that DW_OP_mod
used
the modulo algorithm for unsigned arithmetic. However, this
decision was
not recorded in the standard. Since that time, consumers have
implemented different implementations of DW_OP_mod.
This proposal seeks to clarify and harmonize the consumer
implementations of the DW_OP_mod operator by defining which
algorithm to
use for signed arithmetic as well as define it for floating point
numbers.
Proposal:
Add DW_OP_mod to the list of operators which do not require integral
base types by changing:
Operations other than DW_OP_abs, DW_OP_div, DW_OP_minus, DW_OP_mul,
DW_OP_neg and DW_OP_plus require integral types of the operand
(either
integral base type or the generic type).
To:
Operations other than DW_OP_abs, DW_OP_div, DW_OP_mod, DW_OP_minus,
DW_OP_mul, DW_OP_neg and DW_OP_plus require integral types of the
operand (either integral base type or the generic type).
Then append the following sentence to the description of the
DW_OP_mod:
The algorithm used to implement modulo shall be the one defined in
The
Art of Computer Programming Volume 1: Fundamental Algorithms
Chapter 2
Section 4. Knuth.
Alternative proposals:
1) Explicitly state in the standard that DW_OP_mod is only defined
for
unsigned integral arithmetic. This effectively standardizes the
Michael
Eager's pronouncement from 2011.
2) Pick any algorithm for modulo that works for signed as well
unsigned
arithmetic and specify that DW_OP_modulo shall follow it. The current
GDB implementation follows Knuth 1.2.4 for signed and unsigned
integral
arithmetic but excludes the algorithm for reals and floating point
numbers.
--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss
--
Dwarf-discuss mailing list
Dwarf-discuss@lists.dwarfstd.org
https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss