From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 75526 invoked by alias); 18 Dec 2015 14:53:24 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 75515 invoked by uid 89); 18 Dec 2015 14:53:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.3 required=5.0 tests=AWL,BAYES_00,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=versa X-HELO: mga02.intel.com Received: from mga02.intel.com (HELO mga02.intel.com) (134.134.136.20) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Dec 2015 14:53:21 +0000 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga101.jf.intel.com with ESMTP; 18 Dec 2015 06:53:20 -0800 X-ExtLoop1: 1 Received: from irsmsx152.ger.corp.intel.com ([163.33.192.66]) by FMSMGA003.fm.intel.com with ESMTP; 18 Dec 2015 06:53:18 -0800 Received: from irsmsx104.ger.corp.intel.com ([169.254.5.138]) by IRSMSX152.ger.corp.intel.com ([169.254.6.143]) with mapi id 14.03.0248.002; Fri, 18 Dec 2015 14:49:52 +0000 From: "Tedeschi, Walfred" To: Pedro Alves , "brobecker@adacore.com" CC: "gdb-patches@sourceware.org" Subject: RE: [PATCH V2 5/5] Adapt siginfo fixup for the new bnd fields. Date: Fri, 18 Dec 2015 14:53:00 -0000 Message-ID: References: <1450371416-24270-1-git-send-email-walfred.tedeschi@intel.com> <1450371416-24270-5-git-send-email-walfred.tedeschi@intel.com> <56741B6D.9040006@redhat.com> In-Reply-To: <56741B6D.9040006@redhat.com> Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2015-12/txt/msg00366.txt.bz2 Pedro, Yes, This way we don't need to rely on the systems where gdb/gdbserver was = compiled. I understood as an intermediate step in that the siginfo buffer from the sy= stem is memcopied to the internal structure and then to compat and vice ver= sa. I.e.: buffer -> nat-> compat (x32). Or=20 Compat (x32) -> nat -> buffer. Thanks for your reviews! Regards, -Fred -----Original Message----- From: Pedro Alves [mailto:palves@redhat.com]=20 Sent: Friday, December 18, 2015 3:43 PM To: Tedeschi, Walfred; brobecker@adacore.com Cc: gdb-patches@sourceware.org Subject: Re: [PATCH V2 5/5] Adapt siginfo fixup for the new bnd fields. On 12/17/2015 04:56 PM, Walfred Tedeschi wrote: > New bnds fields will be always present for x86 architecture. > Fixup for compatibility layer 32bits has to be fixed. >=20 > It was added the nat_siginfo to serving as intermediate step between=20 > kernel provided siginfo and the fix up routine. >=20 > When executing compat_siginfo_from_siginfo or=20 > compat_x32_siginfo_from_siginfo first the buffer read from the kernel=20 > are converted into the nat_signfo for homogenization, then the fields=20 > of nat_siginfo are use to set the compat and compat_x32 siginfo structure= s. >=20 > When executing siginfo_from_compat_siginfo or=20 > siginfo_from_compat_x32_siginfo the process happens in oposite order. >=20 > In doing this the fixups become more independent of the system underneath. Can you expand on the rationale? AFAICS, there's no intermediate step conv= ersion, in the sense of a field-by-field conversion. It's a straight memcpy to/from the host's siginfo_t. So is the reason for this new type so that we don't rely on the siginfo_t h= ost's type at all? So that we can access the new fields even if gdb is not= compiled on a system with the updated glibc yet? Thanks, Pedro Alves >=20 > Caveat: No support for MPX on x32. >=20 > 2015-12-08 Walfred Tedeschi >=20 > * amd64-linux-siginfo.c (nat_siginfo_t, nat_sigval_t, nat_timeval): > New types. > (compat_siginfo): New bnd fields added. > (compat_x32_siginfo): New field added. > (cpt_si_addr_lsb): New define. > (compat_siginfo_from_siginfo): Use nat_siginfo. > (siginfo_from_compat_siginfo): Use nat_siginfo. > (compat_x32_siginfo_from_siginfo): Likewise. > (siginfo_from_compat_x32_siginfo): Likewise. >=20 > --- > gdb/nat/amd64-linux-siginfo.c | 311=20 > ++++++++++++++++++++++++++++-------------- > 1 file changed, 211 insertions(+), 100 deletions(-) >=20 > diff --git a/gdb/nat/amd64-linux-siginfo.c=20 > b/gdb/nat/amd64-linux-siginfo.c index 22e3552..8f0f486 100644 > --- a/gdb/nat/amd64-linux-siginfo.c > +++ b/gdb/nat/amd64-linux-siginfo.c > @@ -30,6 +30,92 @@ > Also, the first step is to make a copy from the original bits to the > internal structure which is the super set. */ >=20=20 > +/* These types below (native_*) define a siginfo type that is layout > + the most complete siginfo available for the architecture. */ > + > +typedef int nat_int_t; > +typedef void* nat_uptr_t; > + > +typedef int nat_time_t; > +typedef int nat_timer_t; > + > +/* For native 64-bit, clock_t in _sigchld is 64bit aligned at 4=20 > +bytes. */ typedef long __attribute__ ((__aligned__ (4)))=20 > +nat_clock_t; > + > +struct nat_timeval > +{ > + nat_time_t tv_sec; > + int tv_usec; > +}; > + > +typedef union nat_sigval > +{ > + nat_int_t sival_int; > + nat_uptr_t sival_ptr; > +} nat_sigval_t; > + > +typedef struct nat_siginfo > +{ > + int si_signo; > + int si_errno; > + int si_code; > + > + union > + { > + int _pad[((128 / sizeof (int)) - 4)]; > + /* kill() */ > + struct > + { > + unsigned int _pid; > + unsigned int _uid; > + } _kill; > + > + /* POSIX.1b timers */ > + struct > + { > + nat_timer_t _tid; > + int _overrun; > + nat_sigval_t _sigval; > + } _timer; > + > + /* POSIX.1b signals */ > + struct > + { > + unsigned int _pid; > + unsigned int _uid; > + nat_sigval_t _sigval; > + } _rt; > + > + /* SIGCHLD */ > + struct > + { > + unsigned int _pid; > + unsigned int _uid; > + int _status; > + nat_clock_t _utime; > + nat_clock_t _stime; > + } _sigchld; > + > + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ > + struct > + { > + nat_uptr_t _addr; > + short int _addr_lsb; > + struct > + { > + nat_uptr_t _lower; > + nat_uptr_t _upper; > + } si_addr_bnd; > + } _sigfault; > + > + /* SIGPOLL */ > + struct > + { > + int _band; > + int _fd; > + } _sigpoll; > + } _sifields; > +} nat_siginfo_t __attribute__ ((__aligned__ (8))); >=20=20 > /* These types below (compat_*) define a siginfo type that is layout > compatible with the siginfo type exported by the 32-bit userspace=20 > @@ -101,6 +187,12 @@ typedef struct compat_siginfo > struct > { > unsigned int _addr; > + short int _addr_lsb; > + struct > + { > + unsigned int _lower; > + unsigned int _upper; > + } si_addr_bnd; > } _sigfault; >=20=20 > /* SIGPOLL */ > @@ -162,6 +254,7 @@ typedef struct compat_x32_siginfo > struct > { > unsigned int _addr; > + unsigned int _addr_lsb; > } _sigfault; >=20=20 > /* SIGPOLL */ > @@ -184,6 +277,7 @@ typedef struct compat_x32_siginfo #define=20 > cpt_si_stime _sifields._sigchld._stime #define cpt_si_ptr=20 > _sifields._rt._sigval.sival_ptr #define cpt_si_addr=20 > _sifields._sigfault._addr > +#define cpt_si_addr_lsb _sifields._sigfault._addr_lsb > #define cpt_si_band _sifields._sigpoll._band #define cpt_si_fd=20 > _sifields._sigpoll._fd >=20=20 > @@ -200,54 +294,58 @@ typedef struct compat_x32_siginfo static void=20=20 > compat_siginfo_from_siginfo (compat_siginfo_t *to, siginfo_t *from) { > + nat_siginfo_t from_nat; > + > + gdb_assert (sizeof (nat_siginfo_t) =3D=3D sizeof (siginfo_t)); memcpy= =20 > + (&from_nat, from, sizeof (from_nat)); > memset (to, 0, sizeof (*to)); >=20=20 > - to->si_signo =3D from->si_signo; > - to->si_errno =3D from->si_errno; > - to->si_code =3D from->si_code; > + to->si_signo =3D from_nat.si_signo; > + to->si_errno =3D from_nat.si_errno; > + to->si_code =3D from_nat.si_code; >=20=20 > if (to->si_code =3D=3D SI_TIMER) > { > - to->cpt_si_timerid =3D from->si_timerid; > - to->cpt_si_overrun =3D from->si_overrun; > - to->cpt_si_ptr =3D (intptr_t) from->si_ptr; > + to->cpt_si_timerid =3D from_nat.cpt_si_timerid; > + to->cpt_si_overrun =3D from_nat.cpt_si_overrun; > + to->cpt_si_ptr =3D (intptr_t) from_nat.cpt_si_ptr; > } > else if (to->si_code =3D=3D SI_USER) > { > - to->cpt_si_pid =3D from->si_pid; > - to->cpt_si_uid =3D from->si_uid; > + to->cpt_si_pid =3D from_nat.cpt_si_pid; > + to->cpt_si_uid =3D from_nat.cpt_si_uid; > } > else if (to->si_code < 0) > { > - to->cpt_si_pid =3D from->si_pid; > - to->cpt_si_uid =3D from->si_uid; > - to->cpt_si_ptr =3D (intptr_t) from->si_ptr; > + to->cpt_si_pid =3D from_nat.cpt_si_pid; > + to->cpt_si_uid =3D from_nat.cpt_si_uid; > + to->cpt_si_ptr =3D (intptr_t) from_nat.cpt_si_ptr; > } > else > { > switch (to->si_signo) > { > case SIGCHLD: > - to->cpt_si_pid =3D from->si_pid; > - to->cpt_si_uid =3D from->si_uid; > - to->cpt_si_status =3D from->si_status; > - to->cpt_si_utime =3D from->si_utime; > - to->cpt_si_stime =3D from->si_stime; > + to->cpt_si_pid =3D from_nat.cpt_si_pid; > + to->cpt_si_uid =3D from_nat.cpt_si_uid; > + to->cpt_si_status =3D from_nat.cpt_si_status; > + to->cpt_si_utime =3D from_nat.cpt_si_utime; > + to->cpt_si_stime =3D from_nat.cpt_si_stime; > break; > case SIGILL: > case SIGFPE: > case SIGSEGV: > case SIGBUS: > - to->cpt_si_addr =3D (intptr_t) from->si_addr; > + to->cpt_si_addr =3D (intptr_t) from_nat.cpt_si_addr; > break; > case SIGPOLL: > - to->cpt_si_band =3D from->si_band; > - to->cpt_si_fd =3D from->si_fd; > + to->cpt_si_band =3D from_nat.cpt_si_band; > + to->cpt_si_fd =3D from_nat.cpt_si_fd; > break; > default: > - to->cpt_si_pid =3D from->si_pid; > - to->cpt_si_uid =3D from->si_uid; > - to->cpt_si_ptr =3D (intptr_t) from->si_ptr; > + to->cpt_si_pid =3D from_nat.cpt_si_pid; > + to->cpt_si_uid =3D from_nat.cpt_si_uid; > + to->cpt_si_ptr =3D (intptr_t) from_nat.cpt_si_ptr; > break; > } > } > @@ -257,57 +355,62 @@ compat_siginfo_from_siginfo (compat_siginfo_t=20 > *to, siginfo_t *from) static void siginfo_from_compat_siginfo=20 > (siginfo_t *to, compat_siginfo_t *from) { > - memset (to, 0, sizeof (*to)); > + nat_siginfo_t to_nat; >=20=20 > - to->si_signo =3D from->si_signo; > - to->si_errno =3D from->si_errno; > - to->si_code =3D from->si_code; > + gdb_assert (sizeof (nat_siginfo_t) =3D=3D sizeof (siginfo_t)); memset= =20 > + (&to_nat, 0, sizeof (to_nat)); >=20=20 > - if (to->si_code =3D=3D SI_TIMER) > + to_nat.si_signo =3D from->si_signo; > + to_nat.si_errno =3D from->si_errno; > + to_nat.si_code =3D from->si_code; > + > + if (to_nat.si_code =3D=3D SI_TIMER) > { > - to->si_timerid =3D from->cpt_si_timerid; > - to->si_overrun =3D from->cpt_si_overrun; > - to->si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; > + to_nat.cpt_si_timerid =3D from->cpt_si_timerid; > + to_nat.cpt_si_overrun =3D from->cpt_si_overrun; > + to_nat.cpt_si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; > } > - else if (to->si_code =3D=3D SI_USER) > + else if (to_nat.si_code =3D=3D SI_USER) > { > - to->si_pid =3D from->cpt_si_pid; > - to->si_uid =3D from->cpt_si_uid; > + to_nat.cpt_si_pid =3D from->cpt_si_pid; > + to_nat.cpt_si_uid =3D from->cpt_si_uid; > } > - if (to->si_code < 0) > + if (to_nat.si_code < 0) > { > - to->si_pid =3D from->cpt_si_pid; > - to->si_uid =3D from->cpt_si_uid; > - to->si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; > + to_nat.cpt_si_pid =3D from->cpt_si_pid; > + to_nat.cpt_si_uid =3D from->cpt_si_uid; > + to_nat.cpt_si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; > } > else > { > - switch (to->si_signo) > + switch (to_nat.si_signo) > { > case SIGCHLD: > - to->si_pid =3D from->cpt_si_pid; > - to->si_uid =3D from->cpt_si_uid; > - to->si_status =3D from->cpt_si_status; > - to->si_utime =3D from->cpt_si_utime; > - to->si_stime =3D from->cpt_si_stime; > + to_nat.cpt_si_pid =3D from->cpt_si_pid; > + to_nat.cpt_si_uid =3D from->cpt_si_uid; > + to_nat.cpt_si_status =3D from->cpt_si_status; > + to_nat.cpt_si_utime =3D from->cpt_si_utime; > + to_nat.cpt_si_stime =3D from->cpt_si_stime; > break; > case SIGILL: > case SIGFPE: > case SIGSEGV: > case SIGBUS: > - to->si_addr =3D (void *) (intptr_t) from->cpt_si_addr; > + to_nat.cpt_si_addr =3D (void *) (intptr_t) from->cpt_si_addr; > + to_nat.cpt_si_addr_lsb =3D (short) from->cpt_si_addr_lsb; > break; > case SIGPOLL: > - to->si_band =3D from->cpt_si_band; > - to->si_fd =3D from->cpt_si_fd; > + to_nat.cpt_si_band =3D from->cpt_si_band; > + to_nat.cpt_si_fd =3D from->cpt_si_fd; > break; > default: > - to->si_pid =3D from->cpt_si_pid; > - to->si_uid =3D from->cpt_si_uid; > - to->si_ptr =3D (void* ) (intptr_t) from->cpt_si_ptr; > + to_nat.cpt_si_pid =3D from->cpt_si_pid; > + to_nat.cpt_si_uid =3D from->cpt_si_uid; > + to_nat.cpt_si_ptr =3D (void* ) (intptr_t) from->cpt_si_ptr; > break; > } > } > + memcpy (to, &to_nat, sizeof (to_nat)); > } >=20=20 > /* Converts the system provided siginfo into compatible x32 siginfo.=20= =20 > */ @@ -315,56 +418,60 @@ static void compat_x32_siginfo_from_siginfo=20 > (compat_x32_siginfo_t *to, > siginfo_t *from) > { > + nat_siginfo_t from_nat; > + > + gdb_assert (sizeof (nat_siginfo_t) =3D=3D sizeof (siginfo_t)); memcpy= =20 > + (&from_nat, from, sizeof (from_nat)); > memset (to, 0, sizeof (*to)); >=20=20 > - to->si_signo =3D from->si_signo; > - to->si_errno =3D from->si_errno; > - to->si_code =3D from->si_code; > + to->si_signo =3D from_nat.si_signo; > + to->si_errno =3D from_nat.si_errno; > + to->si_code =3D from_nat.si_code; >=20=20 > if (to->si_code =3D=3D SI_TIMER) > { > - to->cpt_si_timerid =3D from->si_timerid; > - to->cpt_si_overrun =3D from->si_overrun; > - to->cpt_si_ptr =3D (intptr_t) from->si_ptr; > + to->cpt_si_timerid =3D from_nat.cpt_si_timerid; > + to->cpt_si_overrun =3D from_nat.cpt_si_overrun; > + to->cpt_si_ptr =3D (intptr_t) from_nat.cpt_si_ptr; > } > else if (to->si_code =3D=3D SI_USER) > { > - to->cpt_si_pid =3D from->si_pid; > - to->cpt_si_uid =3D from->si_uid; > + to->cpt_si_pid =3D from_nat.cpt_si_pid; > + to->cpt_si_uid =3D from_nat.cpt_si_uid; > } > else if (to->si_code < 0) > { > - to->cpt_si_pid =3D from->si_pid; > - to->cpt_si_uid =3D from->si_uid; > - to->cpt_si_ptr =3D (intptr_t) from->si_ptr; > + to->cpt_si_pid =3D from_nat.cpt_si_pid; > + to->cpt_si_uid =3D from_nat.cpt_si_uid; > + to->cpt_si_ptr =3D (intptr_t) from_nat.cpt_si_ptr; > } > else > { > switch (to->si_signo) > { > case SIGCHLD: > - to->cpt_si_pid =3D from->si_pid; > - to->cpt_si_uid =3D from->si_uid; > - to->cpt_si_status =3D from->si_status; > - memcpy (&to->cpt_si_utime, &from->si_utime, > + to->cpt_si_pid =3D from_nat.cpt_si_pid; > + to->cpt_si_uid =3D from_nat.cpt_si_uid; > + to->cpt_si_status =3D from_nat.cpt_si_status; > + memcpy (&to->cpt_si_utime, &from_nat.cpt_si_utime, > sizeof (to->cpt_si_utime)); > - memcpy (&to->cpt_si_stime, &from->si_stime, > + memcpy (&to->cpt_si_stime, &from_nat.cpt_si_stime, > sizeof (to->cpt_si_stime)); > break; > case SIGILL: > case SIGFPE: > case SIGSEGV: > case SIGBUS: > - to->cpt_si_addr =3D (intptr_t) from->si_addr; > + to->cpt_si_addr =3D (intptr_t) from_nat.cpt_si_addr; > break; > case SIGPOLL: > - to->cpt_si_band =3D from->si_band; > - to->cpt_si_fd =3D from->si_fd; > + to->cpt_si_band =3D from_nat.cpt_si_band; > + to->cpt_si_fd =3D from_nat.cpt_si_fd; > break; > default: > - to->cpt_si_pid =3D from->si_pid; > - to->cpt_si_uid =3D from->si_uid; > - to->cpt_si_ptr =3D (intptr_t) from->si_ptr; > + to->cpt_si_pid =3D from_nat.cpt_si_pid; > + to->cpt_si_uid =3D from_nat.cpt_si_uid; > + to->cpt_si_ptr =3D (intptr_t) from_nat.cpt_si_ptr; > break; > } > } > @@ -375,59 +482,63 @@ static void > siginfo_from_compat_x32_siginfo (siginfo_t *to, > compat_x32_siginfo_t *from) > { > - memset (to, 0, sizeof (*to)); > + nat_siginfo_t to_nat; >=20=20 > - to->si_signo =3D from->si_signo; > - to->si_errno =3D from->si_errno; > - to->si_code =3D from->si_code; > + gdb_assert (sizeof (nat_siginfo_t) =3D=3D sizeof (siginfo_t)); memset= =20 > + (&to_nat, 0, sizeof (to_nat)); >=20=20 > - if (to->si_code =3D=3D SI_TIMER) > + to_nat.si_signo =3D from->si_signo; > + to_nat.si_errno =3D from->si_errno; > + to_nat.si_code =3D from->si_code; > + > + if (to_nat.si_code =3D=3D SI_TIMER) > { > - to->si_timerid =3D from->cpt_si_timerid; > - to->si_overrun =3D from->cpt_si_overrun; > - to->si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; > + to_nat.cpt_si_timerid =3D from->cpt_si_timerid; > + to_nat.cpt_si_overrun =3D from->cpt_si_overrun; > + to_nat.cpt_si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; > } > - else if (to->si_code =3D=3D SI_USER) > + else if (to_nat.si_code =3D=3D SI_USER) > { > - to->si_pid =3D from->cpt_si_pid; > - to->si_uid =3D from->cpt_si_uid; > + to_nat.cpt_si_pid =3D from->cpt_si_pid; > + to_nat.cpt_si_uid =3D from->cpt_si_uid; > } > - if (to->si_code < 0) > + if (to_nat.si_code < 0) > { > - to->si_pid =3D from->cpt_si_pid; > - to->si_uid =3D from->cpt_si_uid; > - to->si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; > + to_nat.cpt_si_pid =3D from->cpt_si_pid; > + to_nat.cpt_si_uid =3D from->cpt_si_uid; > + to_nat.cpt_si_ptr =3D (void *) (intptr_t) from->cpt_si_ptr; > } > else > { > - switch (to->si_signo) > + switch (to_nat.si_signo) > { > case SIGCHLD: > - to->si_pid =3D from->cpt_si_pid; > - to->si_uid =3D from->cpt_si_uid; > - to->si_status =3D from->cpt_si_status; > - memcpy (&to->si_utime, &from->cpt_si_utime, > - sizeof (to->si_utime)); > - memcpy (&to->si_stime, &from->cpt_si_stime, > - sizeof (to->si_stime)); > + to_nat.cpt_si_pid =3D from->cpt_si_pid; > + to_nat.cpt_si_uid =3D from->cpt_si_uid; > + to_nat.cpt_si_status =3D from->cpt_si_status; > + memcpy (&to_nat.cpt_si_utime, &from->cpt_si_utime, > + sizeof (to_nat.cpt_si_utime)); > + memcpy (&to_nat.cpt_si_stime, &from->cpt_si_stime, > + sizeof (to_nat.cpt_si_stime)); > break; > case SIGILL: > case SIGFPE: > case SIGSEGV: > case SIGBUS: > - to->si_addr =3D (void *) (intptr_t) from->cpt_si_addr; > + to_nat.cpt_si_addr =3D (void *) (intptr_t) from->cpt_si_addr; > break; > case SIGPOLL: > - to->si_band =3D from->cpt_si_band; > - to->si_fd =3D from->cpt_si_fd; > + to_nat.cpt_si_band =3D from->cpt_si_band; > + to_nat.cpt_si_fd =3D from->cpt_si_fd; > break; > default: > - to->si_pid =3D from->cpt_si_pid; > - to->si_uid =3D from->cpt_si_uid; > - to->si_ptr =3D (void* ) (intptr_t) from->cpt_si_ptr; > + to_nat.cpt_si_pid =3D from->cpt_si_pid; > + to_nat.cpt_si_uid =3D from->cpt_si_uid; > + to_nat.cpt_si_ptr =3D (void* ) (intptr_t) from->cpt_si_ptr; > break; > } > } > + memcpy (to, &to_nat, sizeof (to_nat)); > } >=20=20 > /* Convert a native/host siginfo object, into/from the siginfo in the >=20 Intel Deutschland GmbH Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany Tel: +49 89 99 8853-0, www.intel.de Managing Directors: Christin Eisenschmid, Christian Lamprechter Chairperson of the Supervisory Board: Nicole Lau Registered Office: Munich Commercial Register: Amtsgericht Muenchen HRB 186928