public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* RFC: AVR interrupt handling issue
@ 2021-12-18 16:00 Ian Molton
  2021-12-18 16:31 ` Henri Cloetens
  0 siblings, 1 reply; 5+ messages in thread
From: Ian Molton @ 2021-12-18 16:00 UTC (permalink / raw)
  To: gcc-help

Hi all,

I posted about this yesterday on the binutils list, but in the light of
day, I find myself re-thinking it;

Right now, gcc will emit ISR prologues and epilogues such as this:

__vector_35:
        push r1          ;
        push r0          ;
        in r0,__SREG__   ; ,
        push r0          ;
        clr __zero_reg__                 ;
        in r0,__RAMPZ__  ; ,
        push r0          ;
        push r18                 ;
	push r19
	push r20                 ;
        push r21                 ;
        push r22                 ;
        push r23                 ;
        push r24                 ;
        push r25                 ;
        push r26                 ;
        push r27                 ;
        push r30                 ;
        push r31                 ;
        push r28                 ;
        push r29                 ;

        // External func call to provoke pro/epilogue
	// generation for this example...
	call foo_func();
	...

	pop r29          ;
        pop r28          ;
        pop r31          ;
        pop r30          ;
        pop r27          ;
        pop r26          ;
        pop r25          ;
        pop r24          ;
        pop r23          ;
        pop r22          ;
        pop r21          ;
        pop r20          ;
        pop r19          ;
        pop r18          ;
        pop r0           ;
        out __RAMPZ__,r0         ; ,
        pop r0           ;
        out __SREG__,r0  ; ,
        pop r0           ;
        pop r1           ;
        reti


The problem I have is that I want to switch to a separate irq stack when
I get an interrupt, which I cannot do in C, since all the prologue is
executed before the function body.

I *can* do it if I use an assembler stub that then calls my ISR, which
switches stacks, and pushes the address of a custom epilogue onto the
stack, before executing the ISR, but this obviously wastes a lot of
cycles pushing the epilogue address, and by necessity, some of the
registers that the existing ISR prologue will redundantly push again.

likewise, being able to insert my own epilogue sequence would allow me
to avoid an additional branch in the return path from the ISR.

I can see two solutions to this problem:

1) Allow the compiler to omit certain registers from being saved in the
ISR prologue

2) Allow the user to specify custom pro/epilogue functions.
(-finstrument functions is similar, but not close enough)


1) would work, but would require careful futzing about with the linker
to arrange the code in such a way that my prologue and epilogue are
located immediately around the ISR code. implementation could look like
-mno-save-isr-prologue="r0,r1,SREG,r26,r27" (or whatever regs the custom
prologue might save prior to the ISR prologue)

2) would be ideal. The compiler would know which registers the custom
prologue functions use, and would therefore be able to omit saving them
from the ISR prologue (and conversely from the epilogue).


Something like

__attribute__ ((naked))
void my_isr_prologue (void)
{
	asm volatile("... whatever" : : : <clobbered regs>);
}

__attribute__ ((naked))
void my_isr_epilogue (void)
{
	asm volatile("... un-whatever" : : : <clobbered regs>);
	asm volatile("reti");
}

__attribute__ ((__isr_prologue__(my_isr_prologue, my_isr_epilogue)))
__attribute__ ((signal))
__vector_35(void)
{

... do interrupt-y things ...

}

Thoguhts? I can see that I could implement option 1) thus:

I specify -mno-gas-isr-prologues to force gcc to emit full
pro/epi-logues in the assembler output.

I can modify gcc/config/avr/avr.c at this point:

(~line 1893)

  avr_regs_to_save (&set);

  if (no-save-isr-prologue)
  {
    // FIXME Remove registers my custom prologue saves from the set
    ...
  }

  if (cfun->machine->is_interrupt || cfun->machine->is_signal)
    {
    ...

which just leaves me with a (trivial) script to write that can stuff my
prologue / epilogue into the assembler, and re-assemble it into an object.

The downside is that very simple ISRs which don't need many registers
will be less efficient. But we're calling C here, and I would write such
simple ISRs in assembler anyway.


Option 2) would require more knowledge of gcc than I currently have.


Other (doomed? cursed?) options:

3)

It almost seems like this could be solved if a function with
__attribute__ ((signal)) could (inline-) call another function with the
same attribute. The first function would not need to save any call-used
registers other than the ones it uses itself, and the called function
would be able to avoid saving any call-used registers that were saved by
its calling function.

I suspect, however that that approach is probably doomed to failure, as
inlining the second function (to avoid the overhead of calling it) would
presumably also relocate its register save instructions right back to
the first functions prologue, where it isn't wanted, as described above.

4)

Use a naked function for the ISR and a script to process the assembler
in order to generate the prologue and epilogue

The GCC docs state that one should not write C code in a naked function.
Presumably, as long as you add enough prologue to provide a C
environment, this isn't a problem, but its explicitly disallowed, and
would require me writing a script to parse the assembler output to
generate the entire prologue/epilogue sequences. In a sense, this is the
"purest" option, but I suspect properly determining the registers used
in this way would be a challenge.

Presumably this is why the __gcc_isr method of generating pro/epilogues
is a task split between GCC and binutils?

I am at a bit of a loss as to what information binutils is supposed to
have in this case, that gcc does not - why *is* it done that way?

I've poked at inline asm with gcc, and find that I can use clobbers to
force a save of RAMPZ (etc.) from inline assembler within an ISR, so I
don't really "get" what the __gcc_isr approach is buying... the ability
to write inline asm without being explicit about clobbers? What for?

Thoughts?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: RFC: AVR interrupt handling issue
  2021-12-18 16:00 RFC: AVR interrupt handling issue Ian Molton
@ 2021-12-18 16:31 ` Henri Cloetens
  2021-12-18 17:47   ` Ian Molton
  2021-12-20 21:06   ` gcc not generating dwarf prologue_end and epilogue_begin .loc directives (was: Re: RFC: AVR interrupt handling issue) Ian Molton
  0 siblings, 2 replies; 5+ messages in thread
From: Henri Cloetens @ 2021-12-18 16:31 UTC (permalink / raw)
  To: gcc-help

Dear Sir,

To customize the stack/unstacking, you need to modify the code of your 
backend port.
I mean, the emitting of the stack/unstacking for the normal case (no 
interrupt, but function call),
is in the backend part, NOT in the 'main' files, that are not intended 
to be modified.
I would recommend you look there, and also in other backends, to find 
out how to do this.

Best Regards,

Henri.


On 12/18/21 5:00 PM, Ian Molton wrote:
> Hi all,
>
> I posted about this yesterday on the binutils list, but in the light of
> day, I find myself re-thinking it;
>
> Right now, gcc will emit ISR prologues and epilogues such as this:
>
> __vector_35:
>          push r1          ;
>          push r0          ;
>          in r0,__SREG__   ; ,
>          push r0          ;
>          clr __zero_reg__                 ;
>          in r0,__RAMPZ__  ; ,
>          push r0          ;
>          push r18                 ;
> 	push r19
> 	push r20                 ;
>          push r21                 ;
>          push r22                 ;
>          push r23                 ;
>          push r24                 ;
>          push r25                 ;
>          push r26                 ;
>          push r27                 ;
>          push r30                 ;
>          push r31                 ;
>          push r28                 ;
>          push r29                 ;
>
>          // External func call to provoke pro/epilogue
> 	// generation for this example...
> 	call foo_func();
> 	...
>
> 	pop r29          ;
>          pop r28          ;
>          pop r31          ;
>          pop r30          ;
>          pop r27          ;
>          pop r26          ;
>          pop r25          ;
>          pop r24          ;
>          pop r23          ;
>          pop r22          ;
>          pop r21          ;
>          pop r20          ;
>          pop r19          ;
>          pop r18          ;
>          pop r0           ;
>          out __RAMPZ__,r0         ; ,
>          pop r0           ;
>          out __SREG__,r0  ; ,
>          pop r0           ;
>          pop r1           ;
>          reti
>
>
> The problem I have is that I want to switch to a separate irq stack when
> I get an interrupt, which I cannot do in C, since all the prologue is
> executed before the function body.
>
> I *can* do it if I use an assembler stub that then calls my ISR, which
> switches stacks, and pushes the address of a custom epilogue onto the
> stack, before executing the ISR, but this obviously wastes a lot of
> cycles pushing the epilogue address, and by necessity, some of the
> registers that the existing ISR prologue will redundantly push again.
>
> likewise, being able to insert my own epilogue sequence would allow me
> to avoid an additional branch in the return path from the ISR.
>
> I can see two solutions to this problem:
>
> 1) Allow the compiler to omit certain registers from being saved in the
> ISR prologue
>
> 2) Allow the user to specify custom pro/epilogue functions.
> (-finstrument functions is similar, but not close enough)
>
>
> 1) would work, but would require careful futzing about with the linker
> to arrange the code in such a way that my prologue and epilogue are
> located immediately around the ISR code. implementation could look like
> -mno-save-isr-prologue="r0,r1,SREG,r26,r27" (or whatever regs the custom
> prologue might save prior to the ISR prologue)
>
> 2) would be ideal. The compiler would know which registers the custom
> prologue functions use, and would therefore be able to omit saving them
> from the ISR prologue (and conversely from the epilogue).
>
>
> Something like
>
> __attribute__ ((naked))
> void my_isr_prologue (void)
> {
> 	asm volatile("... whatever" : : : <clobbered regs>);
> }
>
> __attribute__ ((naked))
> void my_isr_epilogue (void)
> {
> 	asm volatile("... un-whatever" : : : <clobbered regs>);
> 	asm volatile("reti");
> }
>
> __attribute__ ((__isr_prologue__(my_isr_prologue, my_isr_epilogue)))
> __attribute__ ((signal))
> __vector_35(void)
> {
>
> ... do interrupt-y things ...
>
> }
>
> Thoguhts? I can see that I could implement option 1) thus:
>
> I specify -mno-gas-isr-prologues to force gcc to emit full
> pro/epi-logues in the assembler output.
>
> I can modify gcc/config/avr/avr.c at this point:
>
> (~line 1893)
>
>    avr_regs_to_save (&set);
>
>    if (no-save-isr-prologue)
>    {
>      // FIXME Remove registers my custom prologue saves from the set
>      ...
>    }
>
>    if (cfun->machine->is_interrupt || cfun->machine->is_signal)
>      {
>      ...
>
> which just leaves me with a (trivial) script to write that can stuff my
> prologue / epilogue into the assembler, and re-assemble it into an object.
>
> The downside is that very simple ISRs which don't need many registers
> will be less efficient. But we're calling C here, and I would write such
> simple ISRs in assembler anyway.
>
>
> Option 2) would require more knowledge of gcc than I currently have.
>
>
> Other (doomed? cursed?) options:
>
> 3)
>
> It almost seems like this could be solved if a function with
> __attribute__ ((signal)) could (inline-) call another function with the
> same attribute. The first function would not need to save any call-used
> registers other than the ones it uses itself, and the called function
> would be able to avoid saving any call-used registers that were saved by
> its calling function.
>
> I suspect, however that that approach is probably doomed to failure, as
> inlining the second function (to avoid the overhead of calling it) would
> presumably also relocate its register save instructions right back to
> the first functions prologue, where it isn't wanted, as described above.
>
> 4)
>
> Use a naked function for the ISR and a script to process the assembler
> in order to generate the prologue and epilogue
>
> The GCC docs state that one should not write C code in a naked function.
> Presumably, as long as you add enough prologue to provide a C
> environment, this isn't a problem, but its explicitly disallowed, and
> would require me writing a script to parse the assembler output to
> generate the entire prologue/epilogue sequences. In a sense, this is the
> "purest" option, but I suspect properly determining the registers used
> in this way would be a challenge.
>
> Presumably this is why the __gcc_isr method of generating pro/epilogues
> is a task split between GCC and binutils?
>
> I am at a bit of a loss as to what information binutils is supposed to
> have in this case, that gcc does not - why *is* it done that way?
>
> I've poked at inline asm with gcc, and find that I can use clobbers to
> force a save of RAMPZ (etc.) from inline assembler within an ISR, so I
> don't really "get" what the __gcc_isr approach is buying... the ability
> to write inline asm without being explicit about clobbers? What for?
>
> Thoughts?



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: RFC: AVR interrupt handling issue
  2021-12-18 16:31 ` Henri Cloetens
@ 2021-12-18 17:47   ` Ian Molton
  2021-12-18 18:07     ` Ian Molton
  2021-12-20 21:06   ` gcc not generating dwarf prologue_end and epilogue_begin .loc directives (was: Re: RFC: AVR interrupt handling issue) Ian Molton
  1 sibling, 1 reply; 5+ messages in thread
From: Ian Molton @ 2021-12-18 17:47 UTC (permalink / raw)
  To: gcc-help

On 18/12/2021 16:31, Henri Cloetens wrote:
> Dear Sir,
> 
> To customize the stack/unstacking, you need to modify the code of
> your backend port.

I can see that - but thats a very invasive thing to change solely for
the use of my project.

I'd prefer to make a more generic change to the backend (I already found
the location), but I dont want to base an entire project off a change
that has no hope of ever being merged into gcc, as would be the case if
I pushed my entire custom IRQ handling into gcc. Theres just no way.

I want to get gcc to either emit modifiable code that I can then
reassemble, or get gcc to understand how to insert custom
"pro-prologues" and "epi-epilogues", as I would have thought such
changes would have more chance of being accepted into the gcc codebase.

> I mean, the emitting of the stack/unstacking for the normal case (no 
> interrupt, but function call), is in the backend part, NOT in the
> 'main' files, that are not intended to be modified. I would recommend
> you look there, and also in other backends, to find out how to do
> this.

I have, as I mentioned in my previous email.


I could modify gcc/config/avr/avr.c here (below), in order to generate
ISR prologues with some register saves omitted (the ones performed in my
own pro-prologue).

This would cause gcc to output trivially modifiable code, which could be
fed to a script that can insert the pro-prologue and epi-epilogue
assembler fragments.


/*  Output function prologue.  */

void
avr_expand_prologue (void)
{
  HARD_REG_SET set;
  HOST_WIDE_INT size;

  size = get_frame_size() + avr_outgoing_args_size();

  cfun->machine->stack_usage = 0;

  /* Prologue: naked.  */
  if (cfun->machine->is_naked)
    {
      return;
    }

/// MODIFY HERE
   if (no-save-isr-prologue)
   {
     // FIXME Remove registers my custom prologue saves from the set
     ...
   }
/// END MODIFICATION

  avr_regs_to_save (&set);

  if (cfun->machine->is_interrupt || cfun->machine->is_signal)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: RFC: AVR interrupt handling issue
  2021-12-18 17:47   ` Ian Molton
@ 2021-12-18 18:07     ` Ian Molton
  0 siblings, 0 replies; 5+ messages in thread
From: Ian Molton @ 2021-12-18 18:07 UTC (permalink / raw)
  To: gcc-help

Replying to myself for a moment - it would appear that
-fcall-used-reg="rXX" would do what I want (in theory), except for:

1) It doesnt appear to be documented much, or even work on AVR.

2) It applies to entire files, but I just want it to apply to one function.

Does anyone know if any work has been done in that direction? or is it
just abandoned?

-Ian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* gcc not generating dwarf prologue_end and epilogue_begin .loc directives (was: Re: RFC: AVR interrupt handling issue)
  2021-12-18 16:31 ` Henri Cloetens
  2021-12-18 17:47   ` Ian Molton
@ 2021-12-20 21:06   ` Ian Molton
  1 sibling, 0 replies; 5+ messages in thread
From: Ian Molton @ 2021-12-20 21:06 UTC (permalink / raw)
  To: Henri Cloetens, gcc-help

Hi all, Henri,

As mentioned before, I'm trying to keep changes to the compiler to a
minimum, however I think that for AVR the information simply isn't
available after assembling. The question becomes "how do I get the
compiler to emit the information I need?"

I've been reading about dwarf2, which appears to be able to identify
prologue endings and epilogue beginnings with the .loc directive, but
the AVR GCC backend does not (afaict) generate prologue_end (or
epilogue_begin) .loc directives.

Reading through the gcc sources, I've found some backends call:

emit_note (NOTE_INSN_PROLOGUE_END);

but AVR does not.

Im unsure if this is what I need or not, though -

I tried adding this to the end of avr_end_prologue(), but this resulted
in the compiler appearing to go into an infinite loop. I think this is
caused by emit_note (NOTE_INSN_PROLOGUE_END) causing gcc to recursively
call avr_end_prologue(), judging by the (infinite) output.

I've also tried adding a avr_output_mi_thunk() function, similar to the
other architectures (arm, riscv) that call emit_note() in this manner,
but this resulted in nothing changing compared with not doing it.

placing the emit_note (NOTE_INSN_PROLOGUE_END) at the end of
avr_expand_prologue() results in avr_asm_function_end_prologue() being
called twice, and still without emitting a .loc directive containing
prologue_end.

If I can get the prologue end and epilogue beginning locations into the
dwarf2 output, I can write some code to patch the object files and
replace the pro/epilogues with the ones I want, directly in the object
files, before they get linked.

So the million dollar question is - why, even with -gdwarf do I not see
any .loc directives for the end of prologues or beginning of epilogues?

-Ian

On 18/12/2021 16:31, Henri Cloetens wrote:
> Dear Sir,
> 
> To customize the stack/unstacking, you need to modify the code of your
> backend port.
> I mean, the emitting of the stack/unstacking for the normal case (no
> interrupt, but function call),
> is in the backend part, NOT in the 'main' files, that are not intended
> to be modified.
> I would recommend you look there, and also in other backends, to find
> out how to do this.
> 
> Best Regards,
> 
> Henri.
> 
> 
> On 12/18/21 5:00 PM, Ian Molton wrote:
>> Hi all,
>>
>> I posted about this yesterday on the binutils list, but in the light of
>> day, I find myself re-thinking it;
>>
>> Right now, gcc will emit ISR prologues and epilogues such as this:
>>
>> __vector_35:
>>          push r1          ;
>>          push r0          ;
>>          in r0,__SREG__   ; ,
>>          push r0          ;
>>          clr __zero_reg__                 ;
>>          in r0,__RAMPZ__  ; ,
>>          push r0          ;
>>          push r18                 ;
>>     push r19
>>     push r20                 ;
>>          push r21                 ;
>>          push r22                 ;
>>          push r23                 ;
>>          push r24                 ;
>>          push r25                 ;
>>          push r26                 ;
>>          push r27                 ;
>>          push r30                 ;
>>          push r31                 ;
>>          push r28                 ;
>>          push r29                 ;
>>
>>          // External func call to provoke pro/epilogue
>>     // generation for this example...
>>     call foo_func();
>>     ...
>>
>>     pop r29          ;
>>          pop r28          ;
>>          pop r31          ;
>>          pop r30          ;
>>          pop r27          ;
>>          pop r26          ;
>>          pop r25          ;
>>          pop r24          ;
>>          pop r23          ;
>>          pop r22          ;
>>          pop r21          ;
>>          pop r20          ;
>>          pop r19          ;
>>          pop r18          ;
>>          pop r0           ;
>>          out __RAMPZ__,r0         ; ,
>>          pop r0           ;
>>          out __SREG__,r0  ; ,
>>          pop r0           ;
>>          pop r1           ;
>>          reti
>>
>>
>> The problem I have is that I want to switch to a separate irq stack when
>> I get an interrupt, which I cannot do in C, since all the prologue is
>> executed before the function body.
>>
>> I *can* do it if I use an assembler stub that then calls my ISR, which
>> switches stacks, and pushes the address of a custom epilogue onto the
>> stack, before executing the ISR, but this obviously wastes a lot of
>> cycles pushing the epilogue address, and by necessity, some of the
>> registers that the existing ISR prologue will redundantly push again.
>>
>> likewise, being able to insert my own epilogue sequence would allow me
>> to avoid an additional branch in the return path from the ISR.
>>
>> I can see two solutions to this problem:
>>
>> 1) Allow the compiler to omit certain registers from being saved in the
>> ISR prologue
>>
>> 2) Allow the user to specify custom pro/epilogue functions.
>> (-finstrument functions is similar, but not close enough)
>>
>>
>> 1) would work, but would require careful futzing about with the linker
>> to arrange the code in such a way that my prologue and epilogue are
>> located immediately around the ISR code. implementation could look like
>> -mno-save-isr-prologue="r0,r1,SREG,r26,r27" (or whatever regs the custom
>> prologue might save prior to the ISR prologue)
>>
>> 2) would be ideal. The compiler would know which registers the custom
>> prologue functions use, and would therefore be able to omit saving them
>> from the ISR prologue (and conversely from the epilogue).
>>
>>
>> Something like
>>
>> __attribute__ ((naked))
>> void my_isr_prologue (void)
>> {
>>     asm volatile("... whatever" : : : <clobbered regs>);
>> }
>>
>> __attribute__ ((naked))
>> void my_isr_epilogue (void)
>> {
>>     asm volatile("... un-whatever" : : : <clobbered regs>);
>>     asm volatile("reti");
>> }
>>
>> __attribute__ ((__isr_prologue__(my_isr_prologue, my_isr_epilogue)))
>> __attribute__ ((signal))
>> __vector_35(void)
>> {
>>
>> ... do interrupt-y things ...
>>
>> }
>>
>> Thoguhts? I can see that I could implement option 1) thus:
>>
>> I specify -mno-gas-isr-prologues to force gcc to emit full
>> pro/epi-logues in the assembler output.
>>
>> I can modify gcc/config/avr/avr.c at this point:
>>
>> (~line 1893)
>>
>>    avr_regs_to_save (&set);
>>
>>    if (no-save-isr-prologue)
>>    {
>>      // FIXME Remove registers my custom prologue saves from the set
>>      ...
>>    }
>>
>>    if (cfun->machine->is_interrupt || cfun->machine->is_signal)
>>      {
>>      ...
>>
>> which just leaves me with a (trivial) script to write that can stuff my
>> prologue / epilogue into the assembler, and re-assemble it into an
>> object.
>>
>> The downside is that very simple ISRs which don't need many registers
>> will be less efficient. But we're calling C here, and I would write such
>> simple ISRs in assembler anyway.
>>
>>
>> Option 2) would require more knowledge of gcc than I currently have.
>>
>>
>> Other (doomed? cursed?) options:
>>
>> 3)
>>
>> It almost seems like this could be solved if a function with
>> __attribute__ ((signal)) could (inline-) call another function with the
>> same attribute. The first function would not need to save any call-used
>> registers other than the ones it uses itself, and the called function
>> would be able to avoid saving any call-used registers that were saved by
>> its calling function.
>>
>> I suspect, however that that approach is probably doomed to failure, as
>> inlining the second function (to avoid the overhead of calling it) would
>> presumably also relocate its register save instructions right back to
>> the first functions prologue, where it isn't wanted, as described above.
>>
>> 4)
>>
>> Use a naked function for the ISR and a script to process the assembler
>> in order to generate the prologue and epilogue
>>
>> The GCC docs state that one should not write C code in a naked function.
>> Presumably, as long as you add enough prologue to provide a C
>> environment, this isn't a problem, but its explicitly disallowed, and
>> would require me writing a script to parse the assembler output to
>> generate the entire prologue/epilogue sequences. In a sense, this is the
>> "purest" option, but I suspect properly determining the registers used
>> in this way would be a challenge.
>>
>> Presumably this is why the __gcc_isr method of generating pro/epilogues
>> is a task split between GCC and binutils?
>>
>> I am at a bit of a loss as to what information binutils is supposed to
>> have in this case, that gcc does not - why *is* it done that way?
>>
>> I've poked at inline asm with gcc, and find that I can use clobbers to
>> force a save of RAMPZ (etc.) from inline assembler within an ISR, so I
>> don't really "get" what the __gcc_isr approach is buying... the ability
>> to write inline asm without being explicit about clobbers? What for?
>>
>> Thoughts?
> 
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-12-20 21:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-18 16:00 RFC: AVR interrupt handling issue Ian Molton
2021-12-18 16:31 ` Henri Cloetens
2021-12-18 17:47   ` Ian Molton
2021-12-18 18:07     ` Ian Molton
2021-12-20 21:06   ` gcc not generating dwarf prologue_end and epilogue_begin .loc directives (was: Re: RFC: AVR interrupt handling issue) Ian Molton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).