Commit Graph

555 Commits

Author SHA1 Message Date
Lancelot Six
f795c529a8 gdb: Replace gdb::optional with std::optional
Since GDB now requires a C++17, we don't need the internally maintained
gdb::optional implementation.  This patch does the following replacing:
  - gdb::optonal -> std::optional
  - gdb::in_place -> std::in_place
  - #include "gdbsupport/gdb_optional.h" -> #include <optional>

This change has mostly been done automatically.  One exception is
gdbsupport/thread-pool which did not use the gdb:: prefix as it already
lives in the gdb namespace.

Change-Id: I19a92fa03e89637bab136c72e34fd351524f65e9
2023-10-13 13:51:34 +00:00
Tom Tromey
76fc0f6213 Give a language to a type
This changes main_type to hold a language, and updates the debug
readers to set this field.  This is done by adding the language to the
type-allocator object.

Note that the non-DWARF readers are changed on a "best effort" basis.

This patch also reimplements type::is_array_like to use the type's
language, and it adds a new type::is_string_like as well.  This in
turn lets us change the Python implementation of these methods to
simply defer to the type.
2023-09-19 13:28:42 -06:00
Tom Tromey
d559227272 Pass a type allocator to init_fixed_point_type
init_fixed_point_type currently takes an objfile and creates its own
type allocator.  However, for a later patch it is more convenient if
this function accepts a type allocator.  This patch makes this change.
2023-09-19 13:28:42 -06:00
Tom Tromey
84914f598e Introduce type::is_array_like and value_to_array
This adds the type::is_array_like method and the value_to_array
function.

The former can be used to see whether a given type is known to be
"array-like".  This is the currently the case for certain
compiler-generated structure types; in particular both the Ada and
Rust compilers do this.
2023-09-05 11:03:00 -06:00
Tom Tromey
dec28322cf Introduce TYPE_SPECIFIC_RUST_STUFF
This adds a new enum constant, TYPE_SPECIFIC_RUST_STUFF, and changes
the DWARF reader to set this on Rust types.  This will be used as a
flag in a later patch.

Note that the size of the type_specific_field bitfield had to be
increased.  I checked that this did not impact the size of main_type.
2023-09-05 11:02:34 -06:00
Simon Marchi
8c329d5c65 gdb: remove TYPE_FIELD_PACKED
Replace with a new equivalent "is_packed" method on struct field.

Change-Id: I78647be3d408b40b63becb6b6f0fca211bede51c
Approved-By: Tom Tromey <tom@tromey.com>
2023-08-31 13:16:15 -04:00
Simon Marchi
3757d2d44f gdb: remove TYPE_FIELD_BITSIZE
Replace with type::field + field::bitsize.

Change-Id: I2a24755a33683e4a2775a6d2a7b7a9ae7362e43a
Approved-By: Tom Tromey <tom@tromey.com>
2023-08-31 13:16:14 -04:00
Simon Marchi
3be8c91910 gdb: remove FIELD_BITSIZE
Replace with field::bitsize.

Change-Id: I400be235d6a1f446d0a4aafac01df5e850185d3a
Approved-By: Tom Tromey <tom@tromey.com>
2023-08-31 13:16:14 -04:00
Simon Marchi
886176b865 gdb: introduce field::bitsize / field::set_bitsize
Add these two methods, rename the field to m_bitsize to make it pseudo
private.

Change-Id: Ief95e5cf106e72f2c22ae47b033d0fa47202b413
Approved-By: Tom Tromey <tom@tromey.com>
2023-08-31 13:16:13 -04:00
Simon Marchi
454977cdc4 gdb: remove TYPE_FIELD_ARTIFICIAL
Replace with type::field + field::is_artificial.

Change-Id: Ie3bacae49d9bd02e83e504c1ce01470aba56a081
Approved-By: Tom Tromey <tom@tromey.com>
2023-08-31 13:16:13 -04:00
Simon Marchi
6c0f749351 gdb: remove FIELD_ARTIFICIAL
Replace uses with field::is_artificial.

Change-Id: I599616fdd9f4b6d044de492e8151aa6130725cd1
Approved-By: Tom Tromey <tom@tromey.com>
2023-08-31 13:16:12 -04:00
Simon Marchi
321d8b3f28 gdb: introduce field::is_artificial / field::set_is_artificial
Add these two methods, rename the field to m_artificial to make it
pseudo private.

Change-Id: If3a3825473d1d79bb586a8a074b87bba9b43fb1a
Approved-By: Tom Tromey <tom@tromey.com>
2023-08-31 13:16:11 -04:00
Tom de Vries
2774f2dad5 [gdb/symtab] Factor out type::{alloc_fields,copy_fields}
After finding this code in buildsym_compunit::finish_block_internal:
...
              ftype->set_fields
                ((struct field *)
                 TYPE_ALLOC (ftype, nparams * sizeof (struct field)));
...
and fixing PR30810 by using TYPE_ZALLOC, I wondered if there were more
locations that needed fixing.

I decided to make things easier to spot by factoring out a new function
alloc_fields:
...
 /* Allocate the fields array of this type, with NFIELDS elements.  If INIT,
     zero-initialize the allocated memory.  */
  void
  type::alloc_fields (unsigned int nfields, bool init = true);
...
where:
- a regular use would be "alloc_fields (nfields)", and
- an exceptional use that needed no initialization would be
  "alloc_fields (nfields, false)".

Pretty soon I discovered that most of the latter cases are due to
initialization by memcpy, so I added two variants of copy_fields as well.

After this rewrite there are 8 uses of set_fields left:
...
gdb/coffread.c:	  type->set_fields (nullptr);
gdb/coffread.c:	  type->set_fields (nullptr);
gdb/coffread.c:	  type->set_fields (nullptr);
gdb/eval.c:  type->set_fields
gdb/gdbtypes.c:  type->set_fields (args);
gdb/gdbtypes.c:  t->set_fields (XRESIZEVEC (struct field, t->fields (),
gdb/dwarf2/read.c:      type->set_fields (new_fields);
gdb/dwarf2/read.c:	      sub_type->set_fields (sub_type->fields () + 1);
...

These fall into the following categories:
- set to nullptr (coffread.c),
- type not owned by objfile or gdbarch (eval.c), and
- modifying an existing fields array, like adding an element at the end or
  dropping an element at the start (the rest).

Tested on x86_64-linux.
2023-08-31 09:37:44 +02:00
Andrew Burgess
bde240e7f8 gdb: fix printf of wchar_t early in a gdb session
Given this test program:

  #include <wchar.h>

  const wchar_t wide_str[] = L"wide string";

  int
  main (void)
  {
    return 0;
  }

I observed this GDB behaviour:

  $ gdb -q /tmp/printf-wchar_t
  Reading symbols from /tmp/printf-wchar_t...
  (gdb) start
  Temporary breakpoint 1 at 0x40110a: file /tmp/printf-wchar_t.c, line 8.
  Starting program: /tmp/printf-wchar_t

  Temporary breakpoint 1, main () at /tmp/printf-wchar_t.c:8
  25	  return 0;
  (gdb) printf "%ls\n", wide_str

  (gdb)

Notice that the printf results in a blank line rather than the
expected 'wide string' output.

I tracked the problem down to printf_wide_c_string (in printcmd.c), in
this function we do this:

  struct type *wctype = lookup_typename (current_language,
					 "wchar_t", NULL, 0);
  int wcwidth = wctype->length ();

the problem here is that 'wchar_t' is a typedef.  If we look at the
comment on type::length() we see this:

  /* Note that if thistype is a TYPEDEF type, you have to call check_typedef.
     But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
     so you only have to call check_typedef once.  Since value::allocate
     calls check_typedef, X->type ()->length () is safe.  */

What this means is that after calling lookup_typename we should call
check_typedef in order to ensure that the length of the typedef has
been setup correctly.  We are not doing this in printf_wide_c_string,
and so wcwidth is incorrectly calculated as 0.  This is what leads GDB
to print an empty string.

We can see in c_string_operation::evaluate (in c-lang.c) an example of
calling check_typedef specifically to fix this exact issue.

Initially I did fix this problem by adding a check_typedef call into
printf_wide_c_string, but then I figured why not move the
check_typedef call up into lookup_typename itself, that feels like it
should be harmless when looking up a non-typedef type, but will avoid
bugs like this when looking up a typedef.  So that's what I did.

I can then remove the extra check_typedef call from c-lang.c, I don't
see any other places where we had extra check_typedef calls.  This
doesn't mean we definitely had bugs -- so long as we never checked the
length, or, if we knew that check_typedef had already been called,
then we would be fine.

I don't see any test regressions after this change, and my new test
case is now passing.

Reviewed-By: Tom Tromey <tom@tromey.com>
2023-07-07 15:20:28 +01:00
Tom de Vries
33b5899fc0 [gdb] Fix typos
Fix a few typos:
- implemention -> implementation
- convertion(s) -> conversion(s)
- backlashes -> backslashes
- signoring -> ignoring
- (un)ambigious -> (un)ambiguous
- occured -> occurred
- hidding -> hiding
- temporarilly -> temporarily
- immediatelly -> immediately
- sillyness -> silliness
- similiar -> similar
- porkuser -> pokeuser
- thats -> that
- alway -> always
- supercede -> supersede
- accomodate -> accommodate
- aquire -> acquire
- priveleged -> privileged
- priviliged -> privileged
- priviledges -> privileges
- privilige -> privilege
- recieve -> receive
- (p)refered -> (p)referred
- succesfully -> successfully
- successfuly -> successfully
- responsability -> responsibility
- wether -> whether
- wich -> which
- disasbleable -> disableable
- descriminant -> discriminant
- construcstor -> constructor
- underlaying -> underlying
- underyling -> underlying
- structureal -> structural
- appearences -> appearances
- terciarily -> tertiarily
- resgisters -> registers
- reacheable -> reachable
- likelyhood -> likelihood
- intepreter -> interpreter
- disassemly -> disassembly
- covnersion -> conversion
- conviently -> conveniently
- atttribute -> attribute
- struction -> struct
- resonable -> reasonable
- popupated -> populated
- namespaxe -> namespace
- intialize -> initialize
- identifer(s) -> identifier(s)
- expection -> exception
- exectuted -> executed
- dungerous -> dangerous
- dissapear -> disappear
- completly -> completely
- (inter)changable -> (inter)changeable
- beakpoint -> breakpoint
- automativ -> automatic
- alocating -> allocating
- agressive -> aggressive
- writting -> writing
- reguires -> requires
- registed -> registered
- recuding -> reducing
- opeartor -> operator
- ommitted -> omitted
- modifing -> modifying
- intances -> instances
- imbedded -> embedded
- gdbaarch -> gdbarch
- exection -> execution
- direcive -> directive
- demanged -> demangled
- decidely -> decidedly
- argments -> arguments
- agrument -> argument
- amespace -> namespace
- targtet -> target
- supress(ed) -> suppress(ed)
- startum -> stratum
- squence -> sequence
- prompty -> prompt
- overlow -> overflow
- memember -> member
- languge -> language
- geneate -> generate
- funcion -> function
- exising -> existing
- dinking -> syncing
- destroh -> destroy
- clenaed -> cleaned
- changep -> changedp (name of variable)
- arround -> around
- aproach -> approach
- whould -> would
- symobl -> symbol
- recuse -> recurse
- outter -> outer
- freeds -> frees
- contex -> context

Tested on x86_64-linux.

Reviewed-By: Tom Tromey <tom@tromey.com>
2023-06-03 22:43:57 +02:00
Tom Tromey
9c0fb73485 Add dynamic_prop::is_constant
I noticed many spots checking whether a dynamic property's kind is
PROP_CONST.  Some spots, I think, are doing a slightly incorrect check
-- checking for != PROP_UNDEFINED where == PROP_CONST is actually
required, the key thing being that const_val may only be called for
PROP_CONST properties.

This patch adds dynamic::is_constant and then updates these checks to
use it.

Regression tested on x86-64 Fedora 36.
2023-05-12 12:30:28 -06:00
Tom Tromey
c819a3380f Replace field_is_static with a method
This changes field_is_static to be a method on struct field, and
updates all the callers.  Most of this patch was written by script.

Regression tested on x86-64 Fedora 36.
2023-05-01 09:20:37 -06:00
Tom Tromey
aeabe83d0a Add frame parameter to resolve_dynamic_type
This adds a frame parameter to resolve_dynamic_type and arranges for
it to be passed through the call tree and, in particular, to all calls
to dwarf2_evaluate_property.

Nothing passes this parameter yet, so this patch should have no
visible effect.

A 'const frame_info_ptr *' is used here to avoid including frame.h
from gdbtypes.h.
2023-03-29 10:16:23 -06:00
Tom Tromey
2d1bc55233 Remove objfile_type
This removes objfile_type, in favor of always using the per-arch
builtins.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
a9a775da56 Add some types to struct builtin_type
This adds some types to struct builtin_type, ensuring it contains all
the types currently used by objfile_type.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
a8ed3dde83 Rename objfile_type to builtin_type
This renames objfile_type to be an overload of builtin_type, in
preparation for their unification.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
526648585c Use type allocator for set types
This changes the set type creation function to accept a type
allocator, and updates all the callers.  Note that symbol readers
should generally allocate on the relevant objfile, regardless of the
underlying type of the set, which is what this patch implements.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
9e76b17aa5 Use type allocator for array types
This changes the array type creation functions to accept a type
allocator, and updates all the callers.  Note that symbol readers
should generally allocate on the relevant objfile, regardless of the
placement of the index type of the array, which is what this patch
implements.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
e727c536c6 Use type allocator for range types
This changes the range type creation functions to accept a type
allocator, and updates all the callers.  Note that symbol readers
should generally allocate on the relevant objfile, regardless of the
underlying type of the range, which is what this patch implements.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
9c794d2d46 Unify arch_pointer_type and init_pointer_type
This unifies arch_pointer_type and init_pointer_type by using a type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
0776344a33 Unify arch_decfloat_type and init_decfloat_type
This unifies arch_decfloat_type and init_decfloat_type by using a type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
77c5f49648 Unify arch_float_type and init_float_type
This unifies arch_float_type and init_float_type by using a type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
46c04ea32f Unify arch_boolean_type and init_boolean_type
This unifies arch_boolean_type and init_boolean_type by using a type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:38 -06:00
Tom Tromey
f50b437c3d Unify arch_character_type and init_character_type
This unifies arch_character_type and init_character_type by using a
type allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:37 -06:00
Tom Tromey
2d39ccd3d1 Unify arch_integer_type and init_integer_type
This unifies arch_integer_type and init_integer_type by using a type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:37 -06:00
Tom Tromey
333859402c Remove init_type
This removes init_type, replacing all uses with the new type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:37 -06:00
Tom Tromey
cc495054ad Remove arch_type
This removes arch_type, replacing all uses with the new type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:37 -06:00
Tom Tromey
8a17bdd9cc Remove alloc_type
This removes alloc_type, replacing all uses with the new type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:37 -06:00
Tom Tromey
9fa83a7ade Remove alloc_type_copy
This removes alloc_type_copy, replacing all uses with the new type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:37 -06:00
Tom Tromey
c9eb9f1854 Remove alloc_type_arch
This removes alloc_type_arch, replacing all uses with the new type
allocator.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:37 -06:00
Tom Tromey
6a4d297c62 Introduce type_allocator
This introduces a new type_allocator class.  This class will be used
to abstract out the placement of new types, so that type-creation code
can be simplified and shared.

Reviewed-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-18 11:12:37 -06:00
Tom Tromey
1cd0716eb1 Move allocate_stub_method to stabsread.c
allocate_stub_method is only called from stabsread.c, and I don't
think it will be needed anywhere else.  So, move it and make it
static.  Tested by rebuilding.
2023-03-10 07:57:45 -07:00
Tom Tromey
5f27603700 Use const for dwarf2_property_baton
Once a baton is stored in a struct type, it doesn't make sense to
modify it.  This patch constifies the API.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-01 15:33:03 -07:00
Tom Tromey
802dace16f Make gdb property batons type-safe
gdbtypes treats dynamic property batons as 'void *', but in actuality
the only users all use dwarf2_property_baton.  This patch changes this
code to be type-safe.  If a new type is needed here, it seems like
that too could be done in a type-safe way.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-03-01 15:33:03 -07:00
Tom Tromey
317c3ed9fc Turn allocate_value into a static "constructor"
This changes allocate_value to be a static "constructor" of value.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13 15:21:07 -07:00
Tom Tromey
d0c9791728 Turn value_type into method
This changes value_type to be a method of value.  Much of this patch
was written by script.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
2023-02-13 15:21:06 -07:00
Tom Tromey
1775f8b380 Increase size of main_type::nfields
main_type::nfields is a 'short', and has been for many years.  PR
c++/29985 points out that 'short' is too narrow for an enum that
contains more than 2^15 constants.

This patch bumps the size of 'nfields'.  To verify that the field
isn't directly used, it is also renamed.  Note that this does not
affect the size of main_type on x86-64 Fedora 36.  And, if it does
have a negative effect somewhere, it's worth considering that types
could be shrunk more drastically by using subclasses for the different
codes.

This is v2 of this patch, which has these changes:

* I changed nfields to 'unsigned', per Simon's request.  I looked at
  changing all the uses, but this quickly fans out into a very large
  patch.  (One additional tweak was needed, though.)

* I wrote a test case.  I discovered that GCC cannot compile a large
  enough C test case, so I resorted to using the DWARF assembler.
  This test doesn't reproduce the crash, but it does fail without the
  patch.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29985
2023-02-09 07:55:34 -07:00
Simon Marchi
43e8c9ce20 gdb: move frame_info_ptr to frame.{c,h}
A patch later in this series will make frame_info_ptr access some
fields internal to frame_info, which we don't want to expose outside of
frame.c.  Move the frame_info_ptr class to frame.h, and the definitions
to frame.c.  Remove frame-info.c and frame-info.h.

Change-Id: Ic5949759e6262ea0da6123858702d48fe5673fea
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
2023-01-20 14:48:57 -05:00
Simon Marchi
1298c32f01 gdb: move call site types to call-site.h
I hesitated between putting  the file in the dwarf2 directory (as
gdb/dwarf2/call-site.h) or in the common directory (as gdb/call-site.h).
The concept of call site is not DWARF-specific, another debug info
reader could provide this information.  But as it is, the implementation
is a bit DWARF-specific, as one form it can take is a DWARF expression
and parameters can be defined using a DWARF register number.  So I ended up
choosing to put it under dwarf2/.  If another debug info reader ever
wants to provide call site information, we can introduce a layer of
abstraction between the "common" call site and the "dwarf2" call site.

The copyright start year comes from the date `struct call_site` was
introduced.

Change-Id: I1cd84aa581fbbf729edc91b20f7d7a6e0377014d
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
2023-01-20 14:48:57 -05:00
Simon Marchi
b23bf9f724 gdb: move sect_offset and cu_offset to dwarf2/types.h
I want to move the call_site stuff out of gdbtypes.h, to a new header
file, to break some cyclic include problem.  The call_site stuff uses
cu_offset, also defined in gdbtypes.h, so cu_offset also needs to move
somewhere else (otherwise, call-site.h will need to include gdbtypes.h,
and we are back to square 1).  I could move cu_offset to the future new
file dwarf2/call-site.h, but it doesn't sound like a good place for it,
at cu_offset is not specific to call sites, it's used throughout
dwarf2/.  So, move it to its own file, dwarf2/types.h.  For now,
gdbtypes.h includes dwarf2/types.h, but that will be removed once the
call site stuff is moved to its own file.

Move sect_offset with it too.  sect_offset is not a DWARF-specific
concept, but for the moment it is only used in dwarf2/.

Change-Id: I1fd2a3b7b67dee789c4874244b044bde7db43d8e
Reviewed-By: Bruno Larsen <blarsen@redhat.com>
2023-01-20 14:48:56 -05:00
Joel Brobecker
213516ef31 Update copyright year range in header of all files managed by GDB
This commit is the result of running the gdb/copyright.py script,
which automated the update of the copyright year range for all
source files managed by the GDB project to be updated to include
year 2023.
2023-01-01 17:01:16 +04:00
Tom Tromey
785545988c Fix crash in is_nocall_function
is_nocall_function anticipates only being called for a function or a
method.  However, PR gdb/29871 points out a situation where an unusual
expression -- but one that parses to a valid, if extremely weird,
function call -- breaks this assumption.

This patch changes is_nocall_function to remove this assert and
instead simply return 'false' in this case.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29871
2022-12-12 21:38:01 -07:00
Tom Tromey
4881fcd7c1 Add missing TYPE_CODE_* constants to Python
A user noticed that TYPE_CODE_FIXED_POINT was not exported by the gdb
Python layer.  This patch fixes the bug, and prevents future
occurences of this type of bug.
2022-10-31 12:47:36 -06:00
Tom Tromey
6c849804cf Fix bug in Ada packed array handling
A user found a bug where an array of packed arrays was printed
incorrectly.  The bug here is that the packed array has a bit stride,
but the outer array does not -- and should not.  However,
update_static_array_size does not distinguish between an array of
packed arrays and a multi-dimensional packed array, and for the
latter, only the innermost array will end up with a stride.

This patch fixes the problem by adding a flag to indicate whether a
given array type is a constituent of a multi-dimensional array.
2022-10-21 09:40:58 -06:00
Tom Tromey
bd2b40ac12 Change GDB to use frame_info_ptr
This changes GDB to use frame_info_ptr instead of frame_info *
The substitution was done with multiple sequential `sed` commands:

sed 's/^struct frame_info;/class frame_info_ptr;/'
sed 's/struct frame_info \*/frame_info_ptr /g' - which left some
    issues in a few files, that were manually fixed.
sed 's/\<frame_info \*/frame_info_ptr /g'
sed 's/frame_info_ptr $/frame_info_ptr/g' - used to remove whitespace
    problems.

The changed files were then manually checked and some 'sed' changes
undone, some constructors and some gets were added, according to what
made sense, and what Tromey originally did

Co-Authored-By: Bruno Larsen <blarsen@redhat.com>
Approved-by: Tom Tomey <tom@tromey.com>
2022-10-10 11:57:10 +02:00