# R8, Retrace and map file versioning

Programs compiled by R8 are not structurally the same as the input. For example,
names, invokes and line numbers can all change when compiling with R8. The
correspondence between the input and the output is recorded in a mapping file.
The mapping file can be used with retrace to recover the original stack trace
from the stack traces produced by running the R8 compiled program. More
information about R8 and mapping files can be found
[here](https://developer.android.com/studio/build/shrink-code#decode-stack-trace).

## Additional information appended as comments to the file

The format for additional information is encoded as comments with json formatted
data. The data has an ID to disambiguate it from other information.

### Version

The version information states what version the content of the mapping file is
using.

The format of the version information is:
```
# {"id":"com.android.tools.r8.mapping","version":"1.0"}
```
Here `id` must be `com.android.tools.r8.mapping` and `version` is the version of
the mapping file.

The version information applies to content of the file following the position of
the version entry until either the end of the file or another version entry is
present.

If no version information is present, the content is assumed to have version
zero and no additional mapping information except [Source File](#source-file).

When interpreting the mapping file, any additional mapping information
pertaining to a later version should be ignored. In other words, treated as a
normal comment.

Retracing tools supporting this versioning scheme should issue a warning when
given mapping files with versions higher than the version supported by the tool.

- Version 1.0 was introduced by R8 in version 3.1.21

### Source File

The source file information states what source file a class originated from.

The source file information must be placed directly below the class mapping it
pertains to. The format of the source file information is:
```
some.package.Class -> foo.a:
# {"id":"sourceFile","fileName":"R8Test.kt"}
```
Here `id` must be the string `sourceFile` and `fileName` is the source file name
as a string value (in this example `R8Test.kt`).

Note that the `id` of the source file information is unqualified. It is the only
allowed unqualified identifier as it was introduced prior to the versioning
scheme.

### Synthesized (Introduced at version 1.0)

The synthesized information states what parts of the compiled output program are
synthesized by the compiler. A retracing tool should use the synthesized
information to strip out synthesized method frames from retraced stacks.

The synthesized information must be placed directly below the class, field or
method mapping it pertains to. The format of the synthesized information is:
```
# {'id':'com.android.tools.r8.synthesized'}
```
Here `id` must be `com.android.tools.r8.synthesized`. There is no other content.

A class mapping would be:
```
some.package.SomeSynthesizedClass -> x.y.z:
# {'id':'com.android.tools.r8.synthesized'}
```
This specifies that the class `x.y.z` has been synthesized by the compiler and
thus it did not exist in the original input program.

Notice that the left-hand side and right-hand side, here
`some.package.SomeSynthesizedClass` and `x.y.z` respectively, could be any class
name. It is likely that the mapping for synthetics is the identity, but a useful
name can be placed here if possible which legacy retrace tools would use when
retracing.

A field mapping would be:
```
some.package.Class -> x.y.z:
  int someField -> a
  # {'id':'com.android.tools.r8.synthesized'}
```
This specifies that the field `x.y.z.a` has been synthesized by the compiler. As
for classes, since the field is not part of the original input program, the
left- and right-hand side names could be anything. Note that a field can be
synthesized without the class being synthesized.

A method mapping would be:
```
some.package.SomeSynthesizedClass -> x.y.z:
  void someMethod() -> a
  # {'id':'com.android.tools.r8.synthesized'}
```
This specifies that the method `x.y.z.a()` has been synthesized by the compiler.
As for classes, since the method is not part of the original input program, the
left- and right-hand side names could be anything. Note that a method can be
synthesized without the class being synthesized.

For inline frames a mapping would be:
```
some.package.Class -> foo.a:
    4:4:void example.Foo.lambda$main$0():225 -> a
    4:4:void run(example.Foo):2 -> a
    # {'id':'com.android.tools.r8.synthesized'}
    5:5:void example.Foo.lambda$main$1():228 -> a
    5:5:void run(example.Foo):4 -> a
    # {'id':'com.android.tools.r8.synthesized'} <-- redundant
```
This specifies that line 4 in the method `foo.a.a` is in a method that has
been synthesized by the compiler. Since the method is either synthesized or not
any extra synthesized comments will have no effect.

Synthesized information should never be placed on inlined frames:
```
some.package.Class -> foo.a:
4:4:void example.Foo.syntheticThatIsInlined():225 -> a
# {'id':'com.android.tools.r8.synthesized'}
4:4:void run(example.Foo):2 -> a
```
In the above, the mapping information suggests that the inline frame
`example.Foo.syntheticThatIsInlined` should be marked as `synthesized`. However,
since that method was not part of the input program it should not be in the
output mapping information at all.

### RewriteFrame (Introduced at version 2.0)

The RewriteFrame information informs the retrace tool that when retracing a
frame it should rewrite it. The mapping information has the form:

```
  # { id: 'com.android.tools.r8.rewriteFrame', "
      conditions: ['throws(<exceptionDescriptor>)'],
      actions: ['removeInnerFrames(<count>)'] }
```

The format is to specify conditions for when the rule should be applied and then
describe the actions to take. The following conditions exist:

- `throws(<exceptionDescriptor>)`: Will be true if the thrown exception above is
`<exceptionDescriptor>`

Conditions can be combined by adding more items to the list. The semantics of
having more elements in the list is that the conditions are AND'ed together. To
achieve OR one should duplicate the information.

Actions describe what should happen to the retraced frames if the condition
holds. Multiple specified actions will be applied from left to right. The
following actions exist:

- `removeInnerFrames(<count>)`: Will remove the number of frames starting with
inner most frame. It is an error to specify a count higher than all frames.

An example could be to remove an inlined frame if a null-pointer-exception is
thrown:

```
some.Class -> a:
  4:4:void other.Class.inlinee():23:23 -> a
  4:4:void caller(other.Class):7 -> a\n"
  # { id: 'com.android.tools.r8.rewriteFrame', "
      conditions: ['throws(Ljava/lang/NullPointerException;)'],
      actions: ['removeInnerFrames(1)'] }
```

When retracing:
```
Exception in thread "main" java.lang.NullPointerException: ...
  at a.a(:4)
```

It will normally retrace to:
```
Exception in thread "main" java.lang.NullPointerException: ...
  at other.Class.inlinee(Class.java:23)
  at some.Class.caller(Class.java:7)
```

Amending the last mapping with the above inline information instructs the
retracer to discard frames above, resulting in the retrace result:
```
Exception in thread "main" java.lang.NullPointerException: ...
  at some.Class.caller(Class.java:7)
```

The `rewriteFrame` information will only be applied if the line that is being
retraced is directly under the exception line.

### Outline (Introduced at version 2.0)

The outline information can be used by compilers to specify that a method is an
outline. It has the following format:

```
# { 'id':'com.android.tools.r8.outline' }
```

When a retracer retraces a frame that has the outline mapping information it
should carry the reported position to the next frame and use the
`outlineCallsite` to obtain the correct position.

### Outline Call Site (Introduced at version 2.0, updated at 2.2)

A position in an outline can correspond to multiple different positions
depending on the context. The information can be stored in the mapping file with
the following format:

```
# { 'id':'com.android.tools.r8.outlineCallsite',
    'positions': {
        'outline_pos_1': callsite_pos_1,
        'outline_pos_2': callsite_pos_2,
         ...
     },
     'outline': 'outline':'La;a()I'
  }
```

The `outline` key was added in 2.2 and should be the residual descriptor of the
outline.

The retracer should when seeing the `outline` information carry the line number
to the next frame. The position should be rewritten by using the positions map
before using the resulting position for further retracing. Here is an example:

```
# { id: 'com.android.tools.r8.mapping', version: '2.0' }
outline.Class -> a:
  1:2:int outline() -> a
# { 'id':'com.android.tools.r8.outline' }
some.Class -> b:
  1:1:void foo.bar.Baz.qux():42:42 -> s
  4:4:int outlineCaller(int):98:98 -> s
  5:5:int outlineCaller(int):100:100 -> s
  27:27:int outlineCaller(int):0:0 -> s
# { 'id':'com.android.tools.r8.outlineCallsite',
    'positions': { '1': 4, '2': 5 },
    'outline':'La;a()I'}
```

Retracing the following stack trace lines:

```
  at a.a(:1)
  at b.s(:27)
```

Should first retrace the first line and see it is an `outline` and then use
the `outlineCallsite` for `b.s` at position `27` to map the read position `1` to
position `4` and then use that to find the actual mapping, resulting in the
retraced stack:

```
  at some.Class.outlineCaller(Class.java:98)
```

It should be such that for all stack traces, if a retracer ever see an outline
the next obfuscated line should contain `outlineCallSite` information.

### Catch all range for methods with a single unique position

If only a single position is needed for retracing a method correctly one can
skip emitting the position and rely on retrace to retrace correctly. To ensure
compatibility R8 emits a catch-all range `0:65535` as such:

```
0:65535:void foo():33:33 -> a
```

It does not matter if the mapping is an inline frame. Catch all ranges should
never be used for overloads.

### Residual signature (Introduced at 2.2)

The residual signature information was added to mitigate the problem with no
right hand side signature in mapping files. The information should be placed
directly under the first occurrence of a field or method.

```
com.bar -> a:
com.foo -> b:
  com.bar m1(int) -> m2,
  # { id: 'com.android.tools.r8.residualsignature', signature:'(Z)a' }
```

Similar for fields:
```
com.bar -> a:
com.foo -> b:
  com.bar f1 -> f2,
  # { id: 'com.android.tools.r8.residualsignature', signature:'a' }
```

If the residual definition has changed arguments or return type then the
signature should be emitted. The residual signature has no effect on retracing
stack traces but they are necessary when interacting with residual signatures
through the Retrace Api or for composing mapping files.